| <!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 > Open Project (Ctrl-Shift-O; |
| ⌘-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 (⌘-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(" [Value=%d, Limit=%d]", 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(" [Value=%d, Limit=%d]", 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 (⌘-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<Item> 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 (⌘-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<Item> items = itemDao.fetchItems(); |
| for (Item item : items) { |
| System.out.println("Found item " + item); |
| } |
| } |
| }</pre></li> |
| |
| <li>Fix imports. Either right-click in the editor and choose Fix Imports, or press |
| Ctrl-Shift-I (⌘-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 > 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<Item> fetchItems() { |
| List<Item> results = new ArrayList<Item>(); |
| 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 (⌘-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 (⌘-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"> |
| <h:body> |
| <strong><h:form> |
| <h:commandButton action="#{itemProcessor.execute}" value="Execute"/> |
| </h:form></strong> |
| </h:body></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 > 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"> |
| <welcome-file-list> |
| <welcome-file>faces/<strong>process.xhtml</strong></welcome-file> |
| </welcome-file-list></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; ⌘-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; |
| ⌘-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 "tag" 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 > 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<Item> fetchItems() { |
| List<Item> results = new ArrayList<Item>(); |
| 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 (⌘-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; ⌘-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 (⌘-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<Item> fetchItems() { |
| List<Item> results = new ArrayList<Item>(); |
| 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<Item> 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&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> |