CDI does not provide eager extensions out of the box. Even though there is @ApplicationScoped that is intended to work in a similar way to eager instantiation - It does not behave in the specified fashion.
I am going to describe how to use CDI extensions to get eagerly instantiated beans following the CDI lifecycle, inside the container. I have used this in Wildfly 8.0.
Step 1: First, write the @Eager Annotation
package me.sumithpuri.test.cdi.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
public @interface Eager
{
}
Step 2: Next, develop the Eager Extension to parse the Annotations.
package me.sumithpuri.test.cdi.extension;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessBean;
import me.sumithpuri.test.cdi.annotation.Eager;
public class EagerExtension implements Extension {
private List<Bean<?>> eagerBeansList = new ArrayList<Bean<?>>();
public <T> void collect(@Observes ProcessBean<T> event) {
if (event.getAnnotated().isAnnotationPresent(Eager.class)
&& event.getAnnotated().isAnnotationPresent(ApplicationScoped.class)) {
System.out.println("debug: found an eager annotation");
eagerBeansList.add(event.getBean());
}
}
public void load(@Observes AfterDeploymentValidation event, BeanManager beanManager) {
for (Bean<?> bean : eagerBeansList) {
System.out.println("debug: eager instantiation will be performed - " + bean.getBeanClass());
// note: toString() is important to instantiate the bean
beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean)).toString();
}
}
}
Step 3: Next, configure the extension, using this single line of code, placed inside META-INF/services/javax.enterprise.inject.spi.Extension
me.sumithpuri.test.cdi.extension.EagerExtension
Step 4: Develop other parts of the application
You can refer to the attached code to develop other parts of the application to test CDI (@Eager)
You may download the code from here. Also, note that even though all lifecycle methods are performed such @PostConstruct, @PreDestroy, etc. - no @Inject is being performed. My assumption is that we have to write another extension to perform this. My request to the CDI creators to provide an @Eager out of the box, so that it can help to develop (and sometime help in test) applications where Dependency Injection can be performed outside of Servlets, Web Services, etc.
[credits to: http://ovaraksin.blogspot.in/2013/02/eager-cdi-beans.html]
No comments:
Post a Comment