CDI (Context Dependency Injection)

Introduction

I will discuss here about the Context Dependency Injection (CDI). First of all I will tell you what is Context Dependency Injection as follows.

Context Dependency Injection (CDI):

  • knit the web and transactional tiers together of the JEE platform
  • is a set of services used together
  • allows developers to use enterprise beans along with Java Server Faces (JSF) technology in web applications
  • is desinged for use with stateful objects
  • provides a great deal of flexibility to integrate various kinds of components in a loosely coupled but typesafe way

CDI is specified by JSR 299, formerly known as Web Beans. Related specifications that CDI uses include the following:

  • JSR 330, Dependency Injection for Java
  • The Managed Beans specification, which is an offshoot of the Java EE 6 platform specification (JSR 316)

CDI Key Features

Type Safety: Instead of injecting objects by a (string) name, CDI uses the Java type to resolve injections. When the type is not sufficient, a Qualifier annotation can be used. This allows the compiler to easily detect errors, and provides easy refactoring.

POJOs: Almost every Java object can be injected by CDI. This includes EJBs, JNDI resources, Persistence Units and Persistence Contexts, as well as any object which previously would have been created by a factory method.

Extensibility: Every CDI container can enhance its functionality by using portable “Extensions”. The attribute “portable” means that those CDI Extensions can run on every CDI container and Java EE 6 server, no matter which vendor. This is accomplished by a well-specified SPI (Service Provider Interface).

Interceptors: It is easier to write your own Interceptors.

Decorators: These allow to dynamically extend the existing interface implementations with business aspects.

Events: CDI specifies a type-safe mechanism to send and receive events with loose coupling.

Service provided by CDI

The most fundamental services provided by CDI are as follows:

Contexts: The ability to bind the lifecycle and interactions of stateful components to well-defined but extensible lifecycle contexts.

Dependency Injection: The ability to inject components into an application in a type-safe way, including the ability to choose at deployment time which implementation of a particular interface to inject

For more information on services please read http://docs.oracle.com/javaee/6/tutorial/doc/giwhl.html

Bean in CDI

In CDI, a bean is a source of contextual objects that define application state and/or logic. A Java EE component is a bean if the lifecycle of its instances may be managed by the container according to the lifecycle context model defined in the CDI specification.

CDI makes it possible to inject more kinds of objects and to inject them into objects that are not container-managed.

Objects that can be injected into CDI

The following kinds of objects can be injected:

  • (Almost) any Java class
  • Session beans
  • Java EE resources: data sources, Java Message Service topics, queues, connection factories, and the like
  • Persistence contexts (JPA EntityManager objects)
  • Producer fields
  • Objects returned by producer methods
  • Web service references
  • Remote enterprise bean references

 Qualifiers

Qualifiers is used to provide various implementations of a particular bean type. A qualifier is an annotation that you apply to a bean. A qualifier type is a Java annotation defined as @Target({METHOD, FIELD, PARAMETER, TYPE}) and @Retention(RUNTIME).

For example, you could declare an @Informal qualifier type and apply it to another class that extends the Hi class. To declare this qualifier type, you would use the following code:

package com.roytuts.cdi;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
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({TYPE, METHOD, FIELD, PARAMETER})
public @interface Informal {}

You can then define a bean class that extends the Hi class and uses this qualifier:

package com.roytuts.cdi;

@Informal
public class Hello extends Hi {
    @override
    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}

Both implementations of the bean can now be used in the application.

If you define a bean with no qualifier, the bean automatically has the qualifier @Default. The unannotated Hi class could be declared as follows:

package com.roytuts.cdi;

import javax.enterprise.inject.Default;

@Default
public class Hi {
    public String greet(String name) {
        return "Hi, " + name + ".";
    }
}

Bean Injection

In order to use the beans you create, you inject them into yet another bean that can then be used by an application, such as a JavaServer Faces application. For example, you might create a bean called Printer into which you would inject one of the Hi beans:

import javax.inject.Inject;

public class Printer {

    @Inject Hi hi;
    ...

This code injects the @Default Hi implementation into the bean. The following code injects the @Informal implementation:

import javax.inject.Inject;

public class Printer {
    
	@Inject @Informal Hi hi;
    ...

More is needed for the complete picture of this bean. Its use of scope needs to be understood. In addition, for a JavaServer Faces application, the bean needs to be accessible through the EL.

EL Names of Beans

To make a bean accessible through the EL, use the @Named built-in qualifier:

import javax.inject.Inject;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class Printer {

    @Inject @Informal Hi hi;
    ...

The @Named qualifier allows you to access the bean by using the bean name, with the first letter in lowercase. For example, a Facelets page would refer to the bean as printer.

You can specify an argument to the @Named qualifier to use a nondefault name:

@Named("MyPrinter")

With this annotation, the Facelets page would refer to the bean as MyPrinter.

Bean Setter and Getter

To make the state of the managed bean accessible, you need to add setter and getter methods for that state. The createSalutation method calls the bean’s greet method, and the getSalutation method retrieves the result.

Once the setter and getter methods have been added, the bean is complete.

package com.roytuts.cdi;

import javax.inject.Inject;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class Printer {

    @Inject @Informal Hi hi;
	
    private String name;
	
    private String salutation;
	
    public void createSalutation() {
        this.salutation = hi.greet(name);
    }
	
    public String getSalutation() {
        return salutation;
    }
	
    public void setName(String name) {
       this.name = name;
    }
	
    public String getName() {
       return name;
    }
	
}

Using Managed Bean in Facelets Page

To use the managed bean in a Facelets page, you typically create a form that uses user interface elements to call its methods and display their results. This example provides a button that asks the user to type a name, retrieves the salutation, and then displays the text in a paragraph below the button:

<h:form id="greetme">
   <p><h:outputLabel value="Enter your name: " for="name"/>
      <h:inputText id="name" value="#{printer.name}"/></p>
   <p><h:commandButton value="Say Hello"
                       action="#{printer.createSalutation}"/></p>
   <p><h:outputText value="#{printer.salutation}"/></p>
</h:form>

That’s all about CDI or Context Dependency Injection.

Leave a Reply

Your email address will not be published. Required fields are marked *