The Hollywood Principle

Tutorial - Introduction to CDI - Contexts and Dependency Injection for Java EE (JSR 299)

One of the most exciting features of CDI is to allow anyone to write powerful extensions to the core Java EE platform, even change core behaviour itself. These extensions are fully portable across any environment which supports CDI. This article provides an overview of the major CDI features, explores a sample web application, and outlines some of the basic mechanisms of the framework.

There are currently three CDI implementations available: JBoss Weld (the Reference Implementation), Apache OpenWebBeans, and Caucho CanDI. Several libraries already provide CDI extensions, such as Apache DeltaSpike, JBoss Seam 3, and Apache MyFaces CODI.

A little bit of history

Originally developed under the name ‘Web Beans’, the CDI specification was created to fill the gaps between Enterprise Java Beans (EJB) on the back end, and JavaServer Faces (JSF) in the view layer. The first draft targeted only Java Enterprise Edition (Java EE), but during the creation of the specification it became obvious that most features were very useful for any Java environment, including Java SE.

At the same time, both Guice and Spring communities had begun an effort to specify the basics of injection as “JSR-330: Dependency Injection for Java” (nicknamed “AtInject”). Considering that it did not make sense to provide a new dependency injection container without collaborating on the actual injection API, the AtInject and CDI expert groups worked closely together to ensure a common solution across dependency injection frameworks. As a result, CDI uses the annotations from the AtInject specification, meaning that every CDI implementation fully implements the AtInject specification, just like Guice and Spring. CDI and AtInject are both included in Java Enterprise Edition 6 (JSR-316) and thus an integral part of almost every Java Enterprise Edition server.

Essential CDI

Before we go on to dive into some code, let’s take a quick look at some key CDI 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) which is part of the JSR-299 specification.
  • Interceptors: It has never been easier to write your own Interceptors. Because of the portable behaviour of JSR-299, they now also run on every EE 6-certified server and on all standalone CDI containers.
  • Decorators: These allow to dynamically extend existing interface implementations with business aspects.
  • Events: CDI specifies a type-safe mechanism to send and receive events with loose coupling.
  • Unified EL integration: EL-2.2 opens a new horizon in regard of flexibility and functionality. CDI provides out-of-the-box support for it!

Diving into CDI

Let’s start by exploring a sample web application. The application allows you to send e-mail via a web form – fairly simple. We only provide code fragments, but they should be enough to get the gist of how CDI is used. After showing each part of the application, we will discuss the details in the next chapter.

For our mail application, we need an “application-scoped” MailService. Application-scoped objects are essentially singletons – the container will ensure you always get the same instance whenever you inject it into your application. The replyTo address is taken from the ConfigurationService which is also application-scoped. Here we see our first injection – the “configuration” field is not set by the application’s code, but is injected by CDI. The @Inject annotation tells CDI to perform the injection.

Listing 1

 

@ApplicationScoped
public class MyMailService implements MailService {
 private @Inject ConfigurationService configuration;

 public send(String from, String to, String body) {
   String replyTo = configuration.getReplyToAddress();
   ... // send the email
 }
}

Our application also identifies the current user (note that it doesn’t try to perform any authentication or authorization, we simply trust everyone!), and the current user is scoped to the HTTP session. CDI provides the session scope, which ensures that you will get the same instance of an object per HTTP Session (in a web application).

By default, CDI beans are not available for use in JSF via the Unified Expression Language. In order to expose it for use by JSF and EL, we add the @Named annotation:

Listing 2

@SessionScoped
@Named
public class User {
 public String getName() {..}
 ..
}

The web page is implemented with JSF 2. We suggest you use a controller class:
@RequestScoped
@Named
public class Mail {
 private @Inject MailService mailService;
 private @Inject User user;
 
 private String text; // + getter and setter
 private String recipient; // + getter and setter 
 
 public String sendMail() {
   mailService.send(user.getName(), recipient, text);
   return "messageSent"; // forward to 'message sent' JSF2 page
 }

}
The only missing part now is the JSF page itself, sendMail.xhtml:
<h:form>
 <h:outputLabel value="Username" for="username"/>
 <h:outputText id="username" value="#{user.name}"/><br/>
 <h:outputLabel value="Recipient" for="recipient"/>
 <h:inputText id="recipient" value="#{mail.recipient}"/><br/>
 <h:outputLabel value="Body" for="body"/>
 <h:inputText id="body" value="#{mail.body}"/><br/>

 <h:commandButton value="Send" action="#{mail.send}"/>
</h:form>

Now that we have a working application, let’s explore some of the CDI features we are using.

 

Pages

Mark Struberg
Mark Struberg
Peter Muir
Peter Muir

What do you think?

JAX Magazine - 2014 - 03 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions