CDI – Injecting Beans

In this article I would like to introduce CDI. As you can find at official oracle web site “Contexts and Dependency Injection (CDI) for the Java EE platform is one of several Java EE 6 features that help to knit together the web tier and the transactional tier of the Java EE platform“.

Yes, that’s it! In my opinion this technology is as easy as poweful to use.

Let’s see how it works.

In my easy example I’d like to Inject a bean inside a JavaServerFace Page and consume it.

Also, I used custom annotation to annotated two differents class instance. I found that from JBoss example “cdi-injection”. I suggest to take a look at it.

These are my annotations class.


package it.sample.ordercdinjection.annotation;

import java.lang.annotation.Documented;
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
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MeatAnnotation {
}

package it.sample.ordercdinjection.annotation;

import java.lang.annotation.Documented;
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
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface VegetableAnnotation {
}

Now the interface definition:


package it.sample.ordercdinjection.bean;

public interface IProduct {

 String processOrder();
}

And here the implementations of this:


package it.sample.ordercdinjection.bean;

import java.util.Date;

import it.sample.ordercdinjection.annotation.MeatAnnotation;

@MeatAnnotation
public class Meat implements IProduct {

 @Override
 public String processOrder() {
  return "Meat processed at " + new DateTime().toString();  
 }

}

package it.sample.ordercdinjection.bean;
import java.util.Date;

import it.sample.ordercdinjection.annotation.VegetableAnnotation;

@VegetableAnnotation
public class Vegetable implements IProduct{

 @Override
 public String processOrder() {
  return "Vegetable processed at " + new DateTime().toString();
 }

}

Now the controller class. In this class I injected the bean “Vegetable” and “Meat” and use them into the JavaServerFace page. Let’s take a look at it.


package it.sample.ordercdinjection.controller;

import it.sample.ordercdinjection.annotation.MeatAnnotation;
import it.sample.ordercdinjection.annotation.VegetableAnnotation;
import it.sample.ordercdinjection.bean.IProduct;

import javax.inject.Inject;
import javax.inject.Named;

@Named("order")
public class OrderController {

 @Inject @VegetableAnnotation
 private IProduct vegetable;
 
 @Inject @MeatAnnotation
 private IProduct meat;
 
 public String getVegetableOrder()
 {
  return vegetable.processOrder();
 }
 
 public String getMeatOrder()
 {
  return meat.processOrder();
 }
}

And now the JavaServerFace page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
    <div>
        Vegetables Order: #{order.vegetableOrder}<br />
        Meats Order: #{order.meatOrder}<br />
    </div>
</body>
</html>

The last point is defined the Jsf listener into the web.xml file:

<?xml version=&quot;1.0&quot; encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>OrderCDInjection</display-name>
	<context-param>
		<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
		<param-value>true</param-value>
	</context-param>

	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
		<welcome-file>index.htm</welcome-file>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.html</welcome-file>
		<welcome-file>default.htm</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>facesServlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>facesServlet</servlet-name>
		<url-pattern>*.xhtml</url-pattern>
	</servlet-mapping>
</web-app>

And not forget the /WEB-INF/beans.xml file into your project. It’s empty but you need it anyway.

Now deploy the application over you application server (I’m using glassfish) and browse http://localhost:8080/OrderCDInjection/order.xhtml

Are you surprised for the result? I don’t mean the example but the technology used.

Now, a typical question, should be: “What is the difference between @EJB and @Inject ?”. In google you can find a lot of answers about this question (more or less correct).

Both annotations let you use bean inside your code. I used @EJB when I’m on application server (like glassfish) and I must use it as remote object, otherwise, specially when I used a POJO class, I used the @Inject annotation.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s