Using Dependency Injection in Java EE 5.0by Debu Panda
Dependency injection, or inversion of control (IOC), is today's latest development craze. IOC containers such as Spring have become popular because they simplify the complexities of enterprise Java that come mostly from Java Naming and Directory Interface (JNDI). In this article, I'll discuss how you can use dependency injection in the upcoming Java EE 5.0 specification for resources and services. I migrated the J2EE 1.4 Blueprint application Java Adventure Builder to use EJB 3.0, web services metadata, and dependency injection; I'll use this application to illustrate concepts in this article.
What is Dependency Injection?
Most enterprise Java applications use external resources and services such as
DataSources, EJBs, or web services. In J2EE 1.4, the client must explicitly declare the dependency on the resources in the deployment descriptor element and obtain a reference to the resource by doing a JNDI lookup.
For example, if you want to use a resource such as a
DataSource or a service such as EJB in J2EE 1.4, you must define it in the deployment descriptor like this:
<ejb-local-ref> <ejb-ref-name>ejb/HelloWorld</ejb-ref-name> <local>oracle.ejb30.HelloWorld</local> </ejb-local-ref>
Then, you'd have to look up the object using JNDI, as follows, before you could use the resource:
Context ic = new InitialContext(); HelloWorld helloWorld = ( HelloWorld)ic.lookup("java:comp/env/ejb/HelloWorld");
This method is not only hard for new Java developers to understand, but also error-prone, and thus, it's blamed for some of the complexities in J2EE 1.4.
Dependency injection is the inverse of JNDI. It lets you declare dependencies and lets the Java EE container handle the complexities of service or resource instantiation and initialization when the resource is required. Based on the declaration of resources using annotations or deployment descriptors, the Java EE 5.0 container injects an instance of the resource when it's required. Figure 1 compares JNDI with dependency injection:
Figure 1. Comparing JNDI and dependency injection
Where Can You Use Dependency Injection?
Dependency injection can only be used by managed classes--those that are managed by Java EE containers such as EJB or servlets--rather than by all classes such as helper classes. For example, if we have an EJB, we can use dependency injection on an EJB 3.0 bean class, but not on a helper class upon which the EJB depends. Java EE 5.0 defines dependency injection of resources and EJB, web services in EJB, web and application client modules. The following table lists the types of classes in web and EJB modules that support dependency injection.
|Container||Type of managed classes||Resource type|
|Servlet, listener classes, web services end-point, JAX-RPC handlers||
DataSource, JMS, Mail, EJB, Environment entries, EntityManager, UserTransaction
|Bean, interceptors, web services end-point||
DataSource, JMS, Mail, Environment entries, EntityManager, EJB Context, UserTransaction, TimerService