Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Contexts and Dependency Injection (CDI): Eager Extensions

DZone's Guide to

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.

· Java Zone ·
Free Resource

Get the Edge with a Professional Java IDE. 30-day free trial.

CDI 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.

Get the Java IDE that understands code & makes developing enjoyable. Level up your code with IntelliJ IDEA. Download the free trial.

Topics:
cdi ,java ,lifecycle management ,eager extensions ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}