Contexts and Dependency Injection (CDI): Eager Extensions
If you want to eagerly instantiate your beans, you might know that CDI doesn't support it out of the box. Fortunately, you can get it working without much trouble.
Join the DZone community and get the full member experience.
Join For FreeCDI does not provide eager extensions out of the box. Even though there is @ApplicationScoped, which 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.
The Process
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 the other parts of the application.
You can refer to the attached code to develop the 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 sometimes help in testing) applications where dependency injection can be performed outside of servlets, web sServices, etc.
Published at DZone with permission of Sumith Puri. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments