Monday Aug 23, 2010

TOTD #144: CDI @Produces for container-managed @Resource

Contexts & Dependency Injection (CDI) in Java EE 6 provides type-safe dependency injection. The type-safety part comes from the fact that no String-based identifiers are used for dependency injection. Instead CDI runtime uses the typing information that is already available in the Java object model.

Java EE 5 already had resource injection available in terms of PersistenceContext, PersistenceUnit, Resource, and others. But they require String-based identifiers to identify the resource to be injected. For example:

  • @PersistenceUnit(unitName="SOME_NAME")
  • @Resource(name="JNDI_NAME")
  • @WebServiceRefs(lookup="JNDI_NAME_OF_WEB_SERVICE_REF")

The main proposition of CDI is type-safety. This Tip Of The Day explains how @Produces annotation provided by CDI can be used to centralize all these String-based resource injection and add a facade of type-safety on them. Specifically, it shows how type-safety can be achieved for @PersistenceUnit. A similar approach can be taken for other String-based resource injections as well.

  1. Create a Singleton-scoped bean or Application-scoped bean as:
    import javax.inject.Singleton;
    
    @Singleton
    public class ApplicationResources {
    
    }
    

    All the Java EE component environment references can be centralized in this bean.
  2. If the PersistenceUnit is currently initialized as:
    @PersistenceUnit(unitName="StatesPU") EntityManagerFactory statesEMF;
    

    in other Java EE components, such as Servlet, then it can be alternatively defined in the type-safe manner using the following steps:
    1. Define a new Qualifier as:
      import static java.lang.annotation.ElementType.TYPE;
      import static java.lang.annotation.ElementType.FIELD;
      import static java.lang.annotation.ElementType.PARAMETER;
      import static java.lang.annotation.ElementType.METHOD;
      import static java.lang.annotation.RetentionPolicy.RUNTIME;
      import java.lang.annotation.Retention;
      import java.lang.annotation.Target;
      import javax.inject.Qualifier;
      
      @Qualifier
      @Retention(RUNTIME)
      @Target({METHOD, FIELD, PARAMETER, TYPE})
      public @interface StatesDatabase {
      }
      
    2. Add the type-safe definition of "EntityManagerFactory" in "ApplicationResources" bean (defined above) as:
      @Produces @PersistenceUnit(unitName="StatesPU") @StatesDatabase EntityManagerFactory statesEMF;
      

    3. The "EntityManagerFactory" can now be injected in the Servlet in a type-safe manner as:
      @Inject @StatesDatabase EntityManagerFactory emf;
      

This procedure can be repeated for other String-based resources as well and thus centralize all of them at one place. And now your application becomes more type-safe! With this TOTD, you can use @Inject for injecting your container- and application-managed resources easily.

Read the latest documentation on Weld (Reference Implementation for CDI and included in GlassFish) for more details.

Technorati: totd cdi javaee6 glassfish weld produces typesafety

About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today