blob: 49fc83c2d7f05ad31fabf6442fd46181ee56a0e0 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Working with Injection and Qualifiers in CDI - NetBeans IDE Tutorial</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="description" content="A demonstration of how to use CDI injection and apply qualifiers to Java EE projects using NetBeans IDE 7.0">
<meta name="keywords" content="NetBeans, IDE, integrated development environment,
Contexts and Dependency Injection, CDI, Web Beans, injection, qualifier">
<link rel="stylesheet" type="text/css" href="../../../netbeans.css">
</head>
<body>
<!--
Copyright (c) 2009, 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<h1>Working with Injection and Qualifiers in CDI</h1>
<p><em>Contributed by Andy Gibson</em></p>
<div class="margin-around">
<div class="feedback-box margin-around float-left" style="margin-right:15px">
<h3>Contexts and Dependency Injection</h3>
<ol>
<li><a href="cdi-intro.html">Getting Started with CDI and JSF 2.0</a></li>
<li><strong>Working with Injection and Qualifiers in CDI</strong>
<ul style="margin: 5px 0 0 -2em">
<li><a href="#inject">Injection: the 'I' in CDI</a></li>
<li><a href="#qualifier">Working with Qualifiers</a></li>
<li><a href="#alternative">Alternative Injection Methods</a></li>
<li><a href="#seealso">See Also</a></li>
</ul></li>
<li><a href="cdi-validate.html">Applying @Alternative Beans and Lifecycle Annotations</a></li>
<li><a href="cdi-events.html">Working with Events in CDI</a></li>
</ol>
</div>
</div>
<img src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" class="stamp" alt="Content on this page applies to NetBeans IDE 7.2, 7.3, 7.4 and 8.0" title="Content on this page applies to the NetBeans IDE 7.2, 7.3, 7.4 and 8.0" >
<p>Contexts and Dependency Injection (CDI), specified by <a href="http://jcp.org/en/jsr/detail?id=299">JSR-299</a>,
is an integral part of Java EE 6 and 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 such as 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.</p>
<p>This tutorial is based on the blog post by Andy Gibson, entitled
<a href="http://www.andygibson.net/blog/index.php/2009/12/22/getting-started-with-cdi-part-2-injection/">Getting
Started with CDI part 2 – Injection</a>. It demonstrates how you can use CDI
injection to <em>inject</em> classes or interfaces into other classes. It
also shows how to apply CDI <em>qualifiers</em> to your code, so that you can
specify which class type should be injected at a given injection point.</p>
<p>NetBeans IDE provides built-in support for Contexts and Dependency Injection,
including the option of generating the <code>beans.xml</code> CDI configuration
file upon project creation, editor and navigation support for annotations, as
well as various wizards for creating commonly used CDI artifacts.</p>
<br style="clear:left;">
<div class="indent">
<p>To complete this tutorial, you need the following software and resources.</p>
<table id="requiredSoftware">
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">7.2, 7.3, 7.4, 8.0, Java EE version</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java
Development Kit (JDK)</a></td>
<td class="tbltd1">version 7 or 8</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://glassfish.dev.java.net/">GlassFish server</a></td>
<td class="tbltd1">Open Source Edition 3.x or 4.x</td>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo.zip">cdiDemo.zip</a></td>
<td class="tbltd1">n/a</td>
</tr>
</tbody>
</table>
<p class="notes"><strong>Notes:</strong></p>
</div>
<ul>
<li>The NetBeans IDE Java bundle also includes the GlassFish Server Open Source Edition
which is a Java EE-compliant container.</li>
<li>The solution sample project for this tutorial can be downloaded:
<a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo2.zip">cdiDemo2.zip</a></li>
</ul>
<br>
<h2 id="inject">Injection: the 'I' in CDI</h2>
<p>CDI is an API for injecting contexts and dependencies. In Seam and Spring, dependencies
work mostly by naming beans and binding them to their injection points by their names.
If you are following this tutorial after having completed <a href="cdi-intro.html">Getting
Started with Contexts and Dependency Injection and JSF 2.0</a>, you have so far only
referenced a managed bean by name from the JSF page when we defined the name for the
bean using the <code>@Named</code> annotation. The primary role of the <code>@Named</code>
annotation is to define the bean for the purpose of resolving EL statements within
the application, usually through the JSF EL resolvers. Injection <em>could</em> be
performed by using names, but this was not how injection in CDI was meant to work
since CDI gives us a much richer way to express injection points and the beans to be
injected into them.</p>
<p>In the following example, you create an <code>ItemProcessor</code> that takes a list
of items from a class that implements the <code>ItemDao</code> interface. You take
advantage of CDI's <code>@Inject</code> annotation to demonstrate how it is possible
to <em>inject</em> a bean into another class. The following diagram depicts the scenario
you construct in this exercise.</p>
<div class="indent">
<img src="../../../images_www/articles/73/javaee/cdi-inject/cdi-diagram-inject.png"
alt="CDI diagram showing objects created in this exercise" class="margin-around"
title="Use CDI injection to loosely couple classes in your application">
</div>
<p class="tips">DAO stands for <em>data access object</em>.</p>
<ol>
<li>Begin by extracting the sample start project from the <code>cdiDemo.zip</code>
file (See the <a href="#requiredSoftware">table listing required resources</a>
above.) Open the project in the IDE by choosing File &gt; Open Project (Ctrl-Shift-O;
&#8984;-Shift-O on Mac), then selecting the project from its location on your
computer.</li>
<li>Right-click the project node in the Projects window and choose Properties.</li>
<li>Select the Run category and confirm that your GlassFish instance is selected in the Server dropdown list. </li>
<li>Create a new <code>Item</code> class, and store it in a new package named
<code>exercise2</code>. Click the New File (
<img src="../../../images_www/articles/73/javaee/cdi-common/new-file-btn.png"
alt="New File button"> ) button or press Ctrl-N (&#8984;-N on Mac) to open the
File wizard.</li>
<li>Select the Java category, then select Java Class. Click Next.</li>
<li>Enter <strong>Item</strong> as the class name, then type in <strong>exercise2</strong>
as the package. (The new package is created upon completing the wizard.)
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/java-class-wizard.png"
alt="Java Class wizard" class="margin-around b-all"
title="Create a new Java class using the File wizard"></li>
<li>Click Finish. The new class and package are generated, and the <code>Item</code>
class opens in the editor.</li>
<li>Create <code>value</code> and <code>limit</code> properties for the <code>Item</code>
POJO, and implement the <code>toString()</code> method. Add the following content
to the class.
<pre class="examplecode">
public class Item {
<strong>private int value;
private int limit;
@Override
public String toString() {
return super.toString() + String.format(&quot; [Value=%d, Limit=%d]&quot;, value,limit);
}</strong>
}</pre></li>
<li>Add getter and setter methods to the class. To do so, ensure that your cursor
is placed between the class definition (i.e., between the class' curly brackets),
then right-click in the editor and choose Insert Code (Alt-Insert; Ctrl-I on Mac).
Choose Getter and Setter.
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/insert-code.png"
alt="Insert Code popup" class="margin-around b-all"
title="Create getters and setters using the Insert Code popup"></li>
<li>Select the <code>Item</code> check box (doing so selects all properties contained
in the class).
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/generate-getters-setters.png"
alt="Generate Getters and Setters dialog" class="margin-around b-all"
title="Select the class checkbox to select all properties contained in the class"></li>
<li>Click Generate. Getter and setter methods are generated for the class.
<pre class="examplecode">
public class Item {
private int value;
private int limit;
<strong>public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}</strong>
@Override
public String toString() {
return super.toString() + String.format(&quot; [Value=%d, Limit=%d]&quot;, value, limit);
}
}</pre></li>
<li>Create a constructor that takes both <code>value</code> and <code>limit</code>
arguments. Again, the IDE can assist with this. Press Ctrl-Space within the
class definition and choose the '<code>Item(int value, int limit) - generate</code>'
option.
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/generate-constructor.png"
alt="Code completion list displayed in editor" class="margin-around b-all"
title="Press Ctrl-Space to utilize the editor's code completion facilities">
<br>
The following constructor is added to the class.
<pre class="examplecode">
public class Item {
<strong>public Item(int value, int limit) {
this.value = value;
this.limit = limit;
}</strong>
private int value;
private int limit;
...</pre></li>
<li>Create an <code>ItemDao</code> interface to define how we get the list of
<code>Item</code> objects. In this test application we anticipate using
multiple implementations, so we will code to interfaces.
<p>
Click the New File (
<img src="../../../images_www/articles/73/javaee/cdi-common/new-file-btn.png"
alt="New File button"> ) button or press Ctrl-N (&#8984;-N on Mac) to open the
File wizard.</p></li>
<li>Select the Java category, then select Java Interface. Click Next.</li>
<li>Type in <strong>ItemDao</strong> as the class name, then enter <strong>exercise2</strong>
as the package.</li>
<li>Click Finish. The new interface is generated and opens in the editor.</li>
<li>Add a method called <code>fetchItems()</code> that returns a <code>List</code> of
<code>Item</code> objects.
<pre class="examplecode">
public interface ItemDao {
<strong>List&lt;Item&gt; fetchItems();</strong>
}</pre>
(Use the editor's hint to add the import statement for <code>java.util.List</code>.)</li>
<li>Create an <code>ItemProcessor</code> class. This is the main class that you will
inject your beans into and execute the process from. For now, you will start
with the DAO and look at how you will inject it into our processor bean.
<p>
Click the New File (
<img src="../../../images_www/articles/73/javaee/cdi-common/new-file-btn.png"
alt="New File button"> ) button or press Ctrl-N (&#8984;-N on Mac) to open the
File wizard.</p></li>
<li>Select the Java category, then select Java Class. Click Next.</li>
<li>Type in <strong>ItemProcessor</strong> as the class name, then enter <strong>exercise2</strong>
as the package. Click Finish.
<p>The new class is generated and opens in the editor.</p></li>
<li>Modify the class as follows:
<pre class="examplecode">
@Named
@RequestScoped
public class ItemProcessor {
private ItemDao itemDao;
public void execute() {
List&lt;Item&gt; items = itemDao.fetchItems();
for (Item item : items) {
System.out.println(&quot;Found item &quot; + item);
}
}
}</pre></li>
<li>Fix imports. Either right-click in the editor and choose Fix Imports, or press
Ctrl-Shift-I (&#8984;-Shift-I on Mac).
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/fix-imports.png"
alt="Fix Imports dialog" class="margin-around b-all"
title="Right-click in the editor and choose Fix Imports to add import statements to the class"></li>
<li>Click OK. Import statements for the following classes are required:
<ul>
<li><code>java.util.List</code></li>
<li><code>javax.inject.Named</code></li>
<li><code>javax.enterprise.context.RequestScoped</code></li>
</ul></li>
<li>Begin with a simple DAO that just creates a list of items and returns a
fixed list of items.
<br><br>
In the Projects window, right-click the <code>exercise2</code> package node
and choose New &gt; Java Class. In the Java Class wizard, name the class
<code>DefaultItemDao</code>. Click Finish.
<img src="../../../images_www/articles/73/javaee/cdi-inject/java-class-wizard2.png"
alt="Java Class wizard" class="margin-around b-all"
title="Create a new Java class using the Java Class wizard"></li>
<li>In the editor, have <code>DefaultItemDao</code> implement the
<code>ItemDao</code> interface, and provide an implementation of
<code>fetchItems()</code>.
<pre class="examplecode">
public class DefaultItemDao <strong>implements ItemDao</strong> {
<strong>@Override
public List&lt;Item&gt; fetchItems() {
List&lt;Item&gt; results = new ArrayList&lt;Item&gt;();
results.add(new Item(34, 7));
results.add(new Item(4, 37));
results.add(new Item(24, 19));
results.add(new Item(89, 32));
return results;
}</strong>
}</pre>
(Press Ctrl-Shift-I (&#8984;-Shift-I on Mac) to add import statements for
<code>java.util.List</code> and <code>java.util.ArrayList</code>.)</li>
<li>Switch to the <code>ItemProcessor</code> class (press Ctrl-Tab). In order
to inject the <code>DefaultItemDao</code> into <code>ItemProcessor</code>,
we add the <code>javax.inject.Inject</code> annotation to the <code>ItemDao</code>
field to indicate that this field is an injection point.
<pre class="examplecode">
<strong>import javax.inject.Inject;</strong>
...
@Named
@RequestScoped
public class ItemProcessor {
<strong>@Inject</strong>
private ItemDao itemDao;
...
}</pre>
<span class="tips">Utilize the editor's code completion support to add the
<code>@Inject</code> annotation and import statement to the class. For
example, type '<code>@Inj</code>', then press Ctrl-Space.</span></li>
<li>Finally, we need some way to call the <code>execute()</code> method on the
<code>ItemProcessor</code>. We can run this in a SE environment, but for
now we'll keep it in a JSF page. Create a new page called <code>process.xhtml</code>
that contains a button to call the <code>execute()</code> method.
<br><br>
Click the New File (
<img src="../../../images_www/articles/73/javaee/cdi-common/new-file-btn.png"
alt="New File button"> ) button or press Ctrl-N (&#8984;-N on Mac) to open
the File wizard.</li>
<li>Select the JavaServer Faces category, then select JSF Page. Click Next.</li>
<li>Type in <strong>process</strong> as the file name, then click Finish.
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/new-jsf-page.png"
alt="JSF Page wizard" class="margin-around b-all"
title="Create a new Facelets page using the JSF file wizard"></li>
<li>In the new <code>process.xhtml</code> file, add a button that is wired to
the <code>ItemProcessor.execute()</code> method. Using EL, the default name
for the managed bean is the same as the class name, but with the first letter
being lower-case (i.e., <code>itemProcessor</code>).
<pre class="examplecode">
&lt;h:body&gt;
<strong>&lt;h:form&gt;
&lt;h:commandButton action=&quot;#{itemProcessor.execute}&quot; value=&quot;Execute&quot;/&gt;
&lt;/h:form&gt;</strong>
&lt;/h:body&gt;</pre></li>
<li>Before running the project, set the <code>process.xhtml</code> file as the
new welcome page in the project's web deployment descriptor.
<br><br>
Use the IDE's Go to File dialog to quickly open the <code>web.xml</code> file.
Choose Navigate &gt; Go to File from the IDE's main menu (Alt-Shift-O;
Ctrl-Shift-O on Mac), then type '<code>web</code>'.
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/go-to-file.png"
alt="Go to File dialog" class="margin-around b-all"
title="Use the Go to File dialog to quickly locate a project file"></li>
<li>Click OK. In the XML view of the <code>web.xml</code> file, make the following
change.
<pre class="examplecode">
&lt;welcome-file-list&gt;
&lt;welcome-file&gt;faces/<strong>process.xhtml</strong>&lt;/welcome-file&gt;
&lt;/welcome-file-list&gt;</pre></li>
<li>Click the Run Project ( <img src="../../../images_www/articles/73/javaee/cdi-common/run-project-btn.png"
alt="Run Project button"> ) button in the IDE's main toolbar. The project
is compiled and deployed to GlassFish, and the <code>process.xhtml</code>
file opens in the browser.</li>
<li>Click the '<code>Execute</code>' button that displays on the page. Switch
back to the IDE and examine the GlassFish server log. The server log displays
in the Output window (Ctrl-4; &#8984;-4 on Mac) under the GlassFish Server tab.
When the button is clicked, the log lists the items from our default DAO
implementation.
<br>
<img src="../../../images_www/articles/73/javaee/cdi-inject/output-window.png"
alt="GlassFish server log in Output window" class="margin-around b-all"
title="Examine the server log in the IDE's Output window">
<br>
<span class="tips">Right-click in the Output window and choose Clear (Ctrl-L;
&#8984;-L on Mac) to clear the log. In the above image, the log was cleared
just prior to clicking the '<code>Execute</code>' button.</span></li>
</ol>
<p>We created a class which implements the <code>ItemDao</code> interface, and when
the application was deployed our managed beans in the module were processed by
the CDI implementation (because of the <code>beans.xml</code> file in the
module). Our <code>@Inject</code> annotation specifies that we want to inject a
managed bean into that field and the only thing we know about the injectable bean
is that it must implement <code>ItemDao</code> or some subtype of that interface.
In this case, the <code>DefaultItemDao</code> class fits the bill perfectly.</p>
<p>What would happen if there were multiple implementations of <code>ItemDao</code>
that could have been injected? CDI would not know which implementation to choose
from and would flag a deploy-time error. To overcome this, you would need to use
a CDI qualifier. Qualifiers are explored in the following section.</p>
<br>
<h2 id="qualifier">Working with Qualifiers</h2>
<p>A CDI qualifier is an annotation that can be applied at the class level to
indicate the kind of bean the class is, and also at the field level (among
other places) to indicate what kind of bean needs to be injected at that
point.</p>
<p>To demonstrate the need for a qualifier in the application we are building,
let's add another DAO class to our application which also implements the
<code>ItemDao</code> interface. The following diagram depicts the scenario
you are constructing in this exercise. CDI must be able to determine which
bean implementation should be used at an injection point. Because there are
two implementations of <code>ItemDao</code>, we can resolve this by creating
a qualifier named <code>Demo</code>. Then, we &quot;tag&quot; both the bean
we want to use, as well as the injection point in <code>ItemProcessor</code>,
with a <code>@Demo</code> annotation.</p>
<div class="indent">
<img src="../../../images_www/articles/73/javaee/cdi-inject/cdi-diagram-qualify.png"
alt="CDI diagram showing objects created in this tutorial" class="margin-around"
title="Use CDI injection and qualifiers to loosely couple classes in your application">
</div>
<p>Perform the following steps.</p>
<ol>
<li>In the Projects window, right-click the <code>exercise2</code> package and
choose New &gt; Java Class.</li>
<li>In the New Java Class wizard, name the new class <strong>AnotherItemDao</strong>
then click Finish. The new class is generated and opens in the editor.</li>
<li>Modify the class as follows, so that it implements the <code>ItemDao</code>
interface, and defines the interface's <code>fetchItems()</code> method.
<pre class="examplecode">
public class AnotherItemDao <strong>implements ItemDao</strong> {
<strong>@Override
public List&lt;Item&gt; fetchItems() {
List&lt;Item&gt; results = new ArrayList&lt;Item&gt;();
results.add(new Item(99, 9));
return results;
}</strong>
}</pre>
<p>Be sure to add import statements for <code>java.util.List</code> and
<code>java.util.ArrayList</code>. To do so, right-click in the editor and
choose Fix Imports, or press Ctrl-Shift-I (&#8984;-Shift-I on Mac).</p>
<p>
Now that there are two classes that implement <code>ItemDao</code>, the
choice is not so clear as to which bean we want to inject.</p></li>
<li>Click the Run Project ( <img src="../../../images_www/articles/73/javaee/cdi-common/run-project-btn.png"
alt="Run Project button"> ) button to run the project. Note that the
project now fails to deploy.
<p class="tips">You probably only need to save the file because the IDE will automatically deploy
the project because Deploy on Save is enabled by default.</p></li>
<li>Examine the server log in the Output window (Ctrl-4; &#8984;-4 on Mac).
You see an error message similar to the following.
<pre class="examplecode">Caused by: org.jboss.weld.DeploymentException: Injection point has ambiguous dependencies.
Injection point: field exercise2.ItemProcessor.itemDao;
Qualifiers: [@javax.enterprise.inject.Default()];
Possible dependencies: [exercise2.DefaultItemDao, exercise2.AnotherItemDao]</pre>
<p class="tips">To wrap text onto multiple lines in the Output window,
right-click and choose Wrap text. This eliminates the need to scroll
horizontally.</p>
<p>
Weld, the implementation for CDI, gives us an ambiguous dependency error
meaning that it cannot determine what bean to use for the given injection
point. Most, if not all of the errors that can occur with regard to CDI
injection in Weld are reported at deployment time, even down to whether
passivation-capable beans are missing a <code>Serializable</code> implementation.</p>
<p>
We could make our <code>itemDao</code> field in the <code>ItemProcessor</code>
a specific type that matches one of the implementation types (<code>AnotherItemDao</code>
or <code>DefaultItemDao</code>) since it would then match one and only one
class type. However, then we would lose the benefits of coding to an interface
and find it harder to change implementations without changing the field type.
A better solution is to instead look at CDI qualifiers.</p>
<p>
When CDI inspects an injection point to find a suitable bean to inject, it
takes not only the class type into account, but also any qualifiers. Without
knowing it, we have already used one qualifier which is the default qualifier
called <code>@Any</code>. Let's create a <code>@Demo</code> qualifier which
we can apply to our <code>DefaultItemDao</code> implementation and also to
the injection point in <code>ItemProcessor</code>.</p>
<p>
The IDE provides a wizard that enables you to generate CDI qualifiers.</p></li>
<li>Click the New File (
<img src="../../../images_www/articles/73/javaee/cdi-common/new-file-btn.png"
alt="New File button"> ) button or press Ctrl-N (&#8984;-N on Mac) to open
the File wizard.</li>
<li>Select the Context and Dependency Injection category, then select Qualifier
Type. Click Next.</li>
<li>Enter <strong>Demo</strong> as the class name, then enter <strong>exercise2</strong>
as the package.</li>
<li>Click Finish. The new <code>Demo</code> qualifier opens in the editor.
<pre class="examplecode">
package exercise2;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
/**
*
* @author nbuser
*/
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Demo {
}</pre>
<p>Next you will add this qualifier to the default DAO implementation at the class level.</p>
</li>
<li>Switch to <code>DefaultItemDao</code> in the editor (press Ctrl-Tab),
then type in '<code>@Demo</code>' above the class definition.
<pre class="examplecode">
<strong>@Demo</strong>
public class DefaultItemDao implements ItemDao {
@Override
public List&lt;Item&gt; fetchItems() {
List&lt;Item&gt; results = new ArrayList&lt;Item&gt;();
results.add(new Item(34, 7));
results.add(new Item(4, 37));
results.add(new Item(24, 19));
results.add(new Item(89, 32));
return results;
}
}</pre>
<span class="tips">After typing '<code>@</code>', press Ctrl-Space to
invoke code completion suggestions. The editor recognizes the
<code>Demo</code> qualifier and lists <code>@Demo</code> as an
option for code completion.</span></li>
<li>Click the Run Project ( <img src="../../../images_www/articles/73/javaee/cdi-common/run-project-btn.png"
alt="Run Project button"> ) button to run the project. The project
builds and deploys without errors.
<p class="notes"><strong>Note.</strong> For this modification you might need to explicitly run the project to redeploy the application
instead of incrementally deploying the changes.</p></li>
<li>In the browser, click the '<code>Execute</code>' button, then return
to the IDE and examine the server log in the Output window.
You see the following output.
<pre class="examplecode">INFO: Found item exercise2.Item@1ef62a93 [Value=99, Limit=9]</pre>
<p>The output lists the item from the <code>AnotherItemDao</code> class. Recall
that we annotated the <code>DefaultItemDao</code> implementation but not the
injection point in <code>ItemProcessor</code>. By adding the <code>@Demo</code>
qualifier to the default DAO implementation, we made the other implementation
a more suitable match for the injection point because it matched on both the
type and the qualifier. The <code>DefaultItemDao</code> currently has the
<code>Demo</code> qualifier which is not on the injection point, thus making
it less suitable.</p>
<p>Next you will add the <code>@Demo</code> annotation to the injection point in <code>ItemProcessor</code>.</p></li>
<li>Switch to <code>ItemProcessor</code> in the editor (press Ctrl-Tab), then make the following change.
<pre class="examplecode">
@Named
@RequestScoped
public class ItemProcessor {
@Inject <strong>@Demo</strong>
private ItemDao itemDao;
public void execute() {
List&lt;Item&gt; items = itemDao.fetchItems();
for (Item item : items) {
System.out.println("Found item " + item);
}
}
}</pre></li>
<li>In the browser, click the '<code>Execute</code>' button, then return
to the IDE and examine the server log in the Output window. You see
output from the default implementation (<code>DefaultItemDao</code>)
again.
<pre class="examplecode">
INFO: Found item exercise2.Item@7b3640f1 [Value=34, Limit=7]
INFO: Found item exercise2.Item@26e1cd69 [Value=4, Limit=37]
INFO: Found item exercise2.Item@3274bc70 [Value=24, Limit=19]
INFO: Found item exercise2.Item@dff76f1 [Value=89, Limit=32]</pre>
<p>This is because you are now matching based on type <em>and</em> qualifiers,
and <code>DefaultItemDao</code> is the only bean with both the correct type
and the <code>@Demo</code> annotation.</p></li>
</ol>
<br>
<h2 id="alternative">Alternative Injection Methods</h2>
<p>There are multiple ways to define an injection point on the injected class. So far
you have annotated the fields that reference the injected object. You do not need
to provide getters and setters for field injection. If you wish to create immutable
managed beans with final fields, you can use injection in the constructor by annotating
the constructor with the <code>@Inject</code> annotation. You can then apply any
annotations to constructor parameters to qualify beans for injection. (Of course,
each parameter has a type that can assist in qualifying beans for injection). A
bean may only have one constructor with injection points defined, but it may
implement more than one constructor.</p>
<div class="indent">
<pre class="examplecode">
@Named
@RequestScoped
public class ItemProcessor {
private final ItemDao itemDao;
@Inject
public ItemProcessor(@Demo ItemDao itemDao) {
this.itemDao = itemDao;
}
}</pre>
</div>
<p>You can also call an initialization method which can be passed a bean that is to
be injected.</p>
<div class="indent">
<pre class="examplecode">
@Named
@RequestScoped
public class ItemProcessor {
private ItemDao itemDao;
@Inject
public void setItemDao(@Demo ItemDao itemDao) {
this.itemDao = itemDao;
}
}</pre>
</div>
<p>While in the above case the setter method is used for initialization, you can create any
method and use it for initialization with as many beans as you want in the method call.
You can also have multiple initialization methods in a bean.</p>
<div class="indent">
<pre class="examplecode">
@Inject
public void initBeans(@Demo ItemDao itemDao, @SomeQualifier SomeType someBean) {
this.itemDao = itemDao;
this.bean = someBean;
}</pre>
</div>
<p>The same rules apply to bean matching regardless of how the injection point is defined.
CDI will try to find the best match based on type and qualifiers and will fail on
deployment if there are multiple matching beans, or no matching beans for an injection
point.</p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback:%20Working%20with%20Injection%20and%20Qualifiers%20in%20CDI">Send Feedback on This Tutorial</a>
</div>
<br style="clear:both;">
<h2 id="seealso">See Also</h2>
<p>Continue to the next installment of this series on Contexts and Dependency Injection:</p>
<ul>
<li><a href="cdi-validate.html">Applying @Alternative Beans and Lifecycle Annotations</a></li>
</ul>
<p>For more information about CDI and Java EE, see the following resources.</p>
<ul>
<li><a href="cdi-intro.html">Getting Started with Contexts and Dependency Injection and JSF 2.0</a></li>
<li><a href="javaee-gettingstarted.html">Getting Started with Java EE Applications</a></li>
<li><a href="http://blogs.oracle.com/enterprisetechtips/entry/using_cdi_and_dependency_injection">Enterprise Tech Tip: Using CDI and Dependency Injection for Java in a JSF 2.0 Application</a></li>
<li><a href="http://download.oracle.com/javaee/6/tutorial/doc/gjbnr.html">The Java EE 6 Tutorial, Part V: Contexts and Dependency Injection for the Java EE Platform</a></li>
<li><a href="http://jcp.org/en/jsr/detail?id=299">JSR 299: Specification for Contexts and Dependency Injection</a></li>
</ul>
</body>
</html>