This article introduces Contexts and Dependency Injection for Java EE (CDI), a key part of theJava EE 6 platform. CDI is standardized via JSR 299, a specification Led by Gavin King that aims to synthesize the best dependency injection features from solutions like Seam, Guice and Spring while adding many useful innovations of its own.
The primary focus of Java EE 5 was the ease-of-use via POJO programming, annotations and convention-over-configuration. Java EE 5 had a basic form of dependency injection. Specifically, you could inject container resources such as data sources, JPA entity managers, entity manager factories and EJBs via the @Resource, @PersistenceContext, @PersistenceUnit and @EJB annotations into Servlets, JSF backing beans and other EJBs. This model was adequate for applications comprising of JPA domain objects, services and DAOs written as EJBs and JSF.
Besides the strictly dependency injection centric features, CDI enhances the Java EE programming model in two important ways, both of which were first introduced by Seam. First, it allows you to use EJBs directly as JSF backing beans. . Second, CDI allows you to manage the scope, state, life-cycle and context for objects in a much more declarative way, rather than the programmatic way most web-oriented frameworks handle managing objects in the request, session and application scopes.
The CDI services are a core aspect of the Java EE platform and include full support for Java EE modularity and the Java EE component architecture. But the specification does not limit the use of CDI to the Java EE environment. In the Java SE environment, the services might be provided by a standalone CDI implementation like Weld, or even by a container that also implements the subset of EJB defined for embedded usage by the EJB 3.1 specification. CDI is especially useful in the context of web application development, but the problems it solves are general development concerns and it is therefore applicable to a wide variety of application.
The primary focus of Java EE 5 was the ease-of-use via POJO programming, annotations and convention-over-configuration. Java EE 5 had a basic form of dependency injection. Specifically, you could inject container resources such as data sources, JPA entity managers, entity manager factories and EJBs via the @Resource, @PersistenceContext, @PersistenceUnit and @EJB annotations into Servlets, JSF backing beans and other EJBs. This model was adequate for applications comprising of JPA domain objects, services and DAOs written as EJBs and JSF.
Besides the strictly dependency injection centric features, CDI enhances the Java EE programming model in two important ways, both of which were first introduced by Seam. First, it allows you to use EJBs directly as JSF backing beans. . Second, CDI allows you to manage the scope, state, life-cycle and context for objects in a much more declarative way, rather than the programmatic way most web-oriented frameworks handle managing objects in the request, session and application scopes.
The CDI services are a core aspect of the Java EE platform and include full support for Java EE modularity and the Java EE component architecture. But the specification does not limit the use of CDI to the Java EE environment. In the Java SE environment, the services might be provided by a standalone CDI implementation like Weld, or even by a container that also implements the subset of EJB defined for embedded usage by the EJB 3.1 specification. CDI is especially useful in the context of web application development, but the problems it solves are general development concerns and it is therefore applicable to a wide variety of application.
First exemple
Not all instances of a bean type are managed instances. Instances created with the Java new operator are not managed. Only instances provided by the CDI BeanManager or through an injection point are managed instances.
Managed instances can have injection performed on them when they are created. Injection points are declared using the @javax.inject.Injectannotation. Suppose that we have a Java class called HelloImpl:
HelloImpl.java
- package hello;
- import javax.enterprise.context.RequestScoped;
- public class HelloImpl implements Hello {
- public HelloImpl () {
- System.out.println("HelloImpl constructor is called");
- }
- @Override
- public String sayHello(String nom){
- return"Hello "+nom;
- }
- }
Where Hello is an interface as shown below:
Hello.java
- package hello;
- public interface Hello {
- public String sayHello(String name);
- }
Tester.java
- package test;
- import hello.Hello;
- import javax.inject.Inject;
- public class Tester {
- private @Inject Hello hello;
- public String print() {
- System.out.println( hello.sayHello("Hazem"));
- }
- }
Here we are not using any 'new' operator. The container takes the responsibility of creating an instance when it is needed. If we inject the interface by using the @Inject annotation, the container find automatically the implementation of the interface and inject it.
Complications could occur if we have more than one implementation of a particular interface because it throws an ambiguity exception while compiling the code. The container is confused which implementation should be injected. We can solve this problem in two ways.
- We directly inject the needed implementation instead of its interface
- We use Qualifier annotation
Qualifier annotation will be discussed in more details in the second part of this series.