Using CDI and Dependency Injection for Java in a JSF 2.0 Application
By edort on Oct 30, 2009
by Roger Kitain
This Tech Tip covers the intersection of three powerful technologies that are part of the Java EE 6 platform: JSR 299: Contexts and Dependency Injection, JSR 330: Dependency Injection For Java, and JSR 314: JavaServer Faces 2.0.
JSR 299: Contexts and Dependency Injection (CDI) defines a set of services for the Java EE environment that makes applications much easier to develop. It provides an architecture that allows Java EE components such as servlets, enterprise beans, and JavaBeans to exist within the lifecycle of an application with well-defined scopes. In addition, CDI services allow Java EE components, including EJB session beans and JavaServer Faces (JSF) managed beans to be injected and to interact in a loosely coupled way by firing and observing events. Perhaps most significantly, CDI unifies and simplifies the EJB and JSF programming models. It allows enterprise beans to act as managed beans in a JSF application. Through its services, CDI brings transactional support to the web tier. This can make it a lot easier to access transactional resources in web applications. For example, CDI services makes it a lot easier to build a Java EE web application that accesses a database with persistence provided by the Java Persistence API.
JSR 330: Dependency Injection For Java introduces a standard set of annotations that can be used for dependency injection. Dependency injection is a popular technique in developing enterprise Java applications. Unfortunately, there has not been a standard approach for annotation-based dependency injection. Dependency Injection For Java changes that by providing a standardized and extensible API for dependency injection. The API comprises a set of annotations for use on injectable classes.
JavaServer Faces technology provides a server-side component framework that is designed to simplify the development of user interfaces (UIs) for Java EE applications. The latest release of the technology, JSR 314: JavaServer Faces 2.0, makes UI development for Java EE applications even easier through support for annotations and the addition of new features such as Facelets and composite components.
This Tech Tip illustrates the use of CDI and Dependency Injection for Java in a JSF 2.0 application.
An Example Application
Let's look at some key parts of a JSF 2.0 application that uses CDI and Dependency Injection for Java. You can find the source code for the application in the sample application package that accompanies this tip. See Running the Sample Code for instructions on how to install and run the application.
Figure 1 shows the UI for the application. The UI prompts a user to guess a number that the system has randomly selected.
The prompt is as follows:
I am thinking of a number between min to max, where min and max
represent the minimum and maximum values allowable as a guess, respectively. The UI displays a text field for the user to enter the number,
a Guess button to submit the number, and a Reset button to restart the game. If the user enters a number that is lower than the correct number,
the UI responds with the message Higher! It also changes the min value in the prompt message to one more than the guessed number. If the user's entry
is too high, the UI responds with the message Lower! and changes the max value in the prompt message to one less than the guessed number. The system
sets a limit for the number of guesses, and with each incorrect guess, the UI displays
a message that tells the user how many guesses remain. The game ends when the user correctly guesses the number or when the user reaches
the limit of guesses.
Here is the code for the application's UI:
The code for the UI should look familiar to you if you develop applications with JSF. In fact, everything on the page is standard JSF 2.0 view markup.
Notice the highlighted expression language (EL) expressions. These expressions refer to a contextual bean instance
game. A contextual bean instance is also known as a managed bean or simply a bean.
Actually, the concept of managed beans goes beyond CDI. Managed beans, which is introduced in Java EE 6, is designed to unify all of the various types of beans in Java EE, including JSF managed beans, enterprise beans, and CDI beans. A managed bean is a Java class that is treated as a managed component by the Java EE container. Optionally, you can give it a name in the same namespace as that used by EJB components. A managed bean can also rely on a small number of container-provided services, mostly related to lifecycle management and resource injection. Other Java EE technologies such as JSF, EJB, and CDI build on this basic definition of a managed bean by adding services. So, for example, a JSF managed bean adds lifecycle scopes, an EJB session bean adds services such as support for transactions, and a CDI bean adds services such as dependency injection.
Returning to the highlighted EL expressions in the code for the UI, the EL expressions bind to various bean properties and methods, as follows:
- The EL expressions in line 17, 24, and 25 bind to bean properties.
- The EL expressions in line 21 bind to bean properties and to a bean validation method.
- The EL expressions in lines 22 and 23 bind to bean action methods.
As you can see, in JSF 2.0, binding to a CDI bean is no different than binding to a typical JSF managed bean.
The Anatomy of a Simple Contextual Bean
As mentioned previously, beans can be bound to a lifecycle context, can be injected, and can interact with other beans in a loosely coupled way by firing and observing events. In addition, a bean may be called directly from Java code, or as you've seen in the UI for the example application, it may be invoked in an EL expression. This enables a JSF page to directly access a bean.
Let's examine the
game bean used in the application. Here is its source code:
Notice especially the following highlighted annotations in the bean.
@Namedannotation in Line 14. This is a Dependency Injection For Java annotation that is used to associate a name with the bean. Because there is no name specified as an argument to the annotation, the name of the bean will be the name of the JavaBean with its first letter made lowercase, that is,
game. The annotation enables the application to reference the bean by that name using the EL expressions in the view.
@SessionScopedannotation in Line 15. This is a CDI annotation that specifies a scope for the bean. All beans have a scope that determines the lifecycle of their instances and which instances of the beans are visible to instances of other beans. The
@SessionScopedannotation declares that this bean is a session scoped bean, meaning that its lifecycle is the lifecycle of the session.
@Injectannotation in Line 23 and line 29. This is a CDI annotation that is used to identify a dependency injection point, that is, a point at which a dependency on a Java class or interface can be injected. In line 23, the annotation identifies a dependency injection point for the
maxNumberfield. Line 23 also specifies a qualifier annotation,
@MaxNumber, that identifies the implementation to inject. Qualifiers are strongly-typed keys that help distinguish different uses of objects of the same type. Later in this tip, you'll learn more about qualifiers. Defining
@MaxNumberas a qualifier annotation enables the injection of the limit value for the maximum number of guesses. In line 29, the
@Injectannotation identifies a dependency injection point for the
randomNumberfield. Line 29 also specifies a qualifier annotation,
@Random, that identifies the implementation to inject. Defining
@Randomas a qualifier annotation enables the injection of a random number that the user needs to guess.
@PostConstructannotation in line 72. This annotation is defined in JSR 250, Common Annotations for the Java Platform. The annotation is used to identify a method that will perform initialization after a component is created. Here, the
reset()method is marked with a
@PostConstructannotation. After the bean is created, the
reset()method initializes a number of variables such as
remainingGuesses, which tracks the remaining number of guesses;
biggest, which holds the value for the maximum number of guesses; and
number, which holds the randomly generated number that the user needs to guess.
You've seen that the bean uses the
@MaxNumber annotations as qualifier annotations.
Now let's see how those annotations are defined.
Here is the definition of the
@Qualifier annotation in line 15 is a Dependency Injection For Java annotation that is used
to identify an annotation as a qualifier annotation. A qualifier identifies a specific implementation of
a Java class or interface to be injected. In order to use a qualifier annotation, you first need to define its
type as a qualifier. You use the
@Qualifier annotation to do that.
@Random as a qualifier annotation enables a random number to be injected into the application.
@Qualifier annotation is also used in the definition of the
@MaxNumber annotation, as shown below:
@Qualifier annotation in line 16 defines
@MaxNumber as a qualifier annotation.
@MaxNumber as a qualifier annotation enables the injection of the maximum number of allowed guesses
into the application.
The Utility Bean
There is one more important component of the application, a utility bean named
Here is what the
Generator bean looks like:
Here are what the highlighted annotations in the bean do:
@ApplicationScopedannotation in line 7 is a CDI annotation that specifies a scope for the class. The annotation declares that an instance of the
Generatorclass exists for the lifecycle of the application.
@Producesannotation in line 15 and line 18 is a CDI annotation that is used to identify a method as a producer method. A producer method is called whenever another bean in the application needs an injected object. In line 15, the producer method is
next(). The method is called by the Beans Manager when the
Gamebean needs to obtain an instance of the next random number. In line 18, the producer method is
getMaxNumber(). The method is called by the Beans Manager when the
Gamebean needs to obtain the maximum number of allowed guesses — in this case, 100.
How the Components Work Together
Let's return to the UI discussed earlier. When a user responds to the prompt and clicks the Guess button, CDI technology goes into action.
The Java EE container automatically instantiates a contextual instance of the
Game bean and the
Game bean is created, its
reset() method is called to initialize a number of variables such as
biggest, which holds the value for the maximum number of guesses, and
number, which holds the randomly generated number
that the user needs to guess.
Game bean gets the maximum number of guesses from its
maxNumber field. Recall that a dependency injection
point with the qualifier annotation,
@MaxNumber, is specified for the
maxNumber field. Recall too that
a producer method,
getMaxNumber(), in the
Generator bean is associated with the
As a result, when the
Game bean accesses the
@MaxNumber field, it calls the
method in the
Generator bean. The
getMaxNumber() method returns the value of the
field, that is, 100.
Game bean takes a similar route to provide a random number for the user to guess. The bean calls the
randomNumber.get() method as part of its post-construct initialization. Recall that a dependency injection point with the
@Random, is specified for the
randomNumber field, and a producer method,
getRandom(), in the
Generator bean is associated with the
@Random qualifier annotation.
As a result, when the
Game bean calls the
randomNumber.get() method, it invokes the
method in the
Generator bean. The
randomNumber.get() method uses the
method of the
java.util.Random class to generate a random number within the range 0 to 100.
Running the Sample Code
A sample application accompanies this tip. To run the sample application, do the following:
- If you haven't already done so, download a recent promoted build or nightly build of the GlassFish v3 Preview application server.
- Download the sample application package, weld-guess.zip
- Extract the contents of the sample application package. You should see the WAR file for the application,
weld-guess.war, as well as folders for the application source code. The source code for the UI is in the
webfolder. The source code for the beans and annotations are in the
- Start the GlassFish v3 Preview application server by entering the following command:
<GFv3_inst>is where you installed the GlassFish v3 Preview application server.
- Deploy the sample application by copying the
weld-guess.warfile to the
- Execute the application by opening a browser and accessing the URL http://localhost:8080/weld-guess
For more information, see the following resources:
- JSR 299: Contexts and Dependency Injection (CDI)
- JSR 330: Dependency Injection For Java
- JSR 314: JavaServer Faces 2.0
- JSR 250: Common Annotations for the Java Platform
- Context And Dependency Injection (JSR 299) and Servlets
About the Author
Roger Kitain is the JavaServer Faces co-specification lead. He has been extensively involved with server-side web technologies and products since 1997. Roger started working on JavaServer Faces technology in 2001, as a member of the reference implementation team. He has experience with Servlet and JSP technologies. Most recently, Roger has been involved with the CDI specification and integration of CDI with the GlassFish container. Read Roger Kitain's blog.