| <!doctype html> |
| <html class="no-js" lang="en" dir="ltr"> |
| <head> |
| <meta charset="utf-8"> |
| <meta http-equiv="x-ua-compatible" content="ie=edge"> |
| <title>Applying @Alternative Beans and Lifecycle Annotations</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta name="description" content="Applying @Alternative Beans and Lifecycle Annotations - Apache NetBeans"> |
| <meta name="author" content="Apache NetBeans"> |
| <meta name="description" content="Applying @Alternative Beans and Lifecycle Annotations - Apache NetBeans"> |
| <meta name="keywords" content="Apache NetBeans, Tutorials, Applying @Alternative Beans and Lifecycle Annotations"> |
| <meta name="generator" content="Apache NetBeans"> |
| <link rel="stylesheet" href="../../../../../../_/css/font-awesome.min.css"> |
| <link rel="alternate" type="application/atom+xml" title="Apache NetBeans Blog" href="https://netbeans.apache.org/blogs/atom" /> |
| <link rel="stylesheet" href="../../../../../../_/css/highlightjs/default.min.css"> |
| <link rel="stylesheet" href="../../../../../../_/css/netbeans.css"> |
| <link rel="apple-touch-icon" sizes="180x180" href="../../../../../../_/images/fav/apple-touch-icon.png"> |
| <link rel="icon" type="image/png" sizes="32x32" href="../../../../../../_/images/fav/favicon-32x32.png"> |
| <link rel="icon" type="image/png" sizes="16x16" href="../../../../../../_/images/fav/favicon-16x16.png"> |
| <link rel="manifest" href="../../../../../../_/images/fav/site.webmanifest"> |
| <link rel="mask-icon" href="../../../../../../_/images/fav/safari-pinned-tab.svg" color="#5bbad5"> |
| <meta name="msapplication-TileColor" content="#ffc40d"> |
| <meta name="theme-color" content="#ffffff"> |
| <link href="../../../../../../_/css/font-open-sans.css" rel="stylesheet"> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| http://www.apache.org/licenses/LICENSE-2.0 |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| </head> |
| <body> |
| <div class="title-bar" data-responsive-toggle="responsive-menu" data-hide-for="medium"> |
| <button type="button" data-toggle="responsive-menu"><i style='font-size: 32px; color: #fff; padding: 8px' class='fa fa-bars'></i></button> |
| <div class="title-bar-title">Apache NetBeans</div> |
| </div> |
| <div class="top-bar" id="responsive-menu"> |
| <div class='top-bar-left'> |
| <a class='title' href="../../../../../../index.html"><img src='../../../../../../_/images/apache-netbeans.svg' style='padding: 8px; height: 48px;'> Apache NetBeans</a> |
| </div> |
| <div class="top-bar-right"> |
| <ul class="vertical medium-horizontal menu" data-responsive-menu="drilldown medium-dropdown"> |
| <li> <input id="search-input" type="text" placeholder="Search the docs"> </li> |
| <li> <a href="../../../../../../front/main/community">Community</a> </li> |
| <li> <a href="../../../../../../front/main/participate">Participate</a> </li> |
| <li> <a href="../../../../../../front/main/blogs">Blog</a></li> |
| <li> <a href="../../../../../../front/main/help">Get Help</a> </li> |
| <li> <a href="https://plugins.netbeans.apache.org/">Plugins</a> </li> |
| <li> <a href="../../../../../../front/main/download">Download</a> </li> |
| </ul> |
| </div> |
| </div> |
| |
| <!-- src/templates/news --> |
| <section class="hero news alternate"> |
| <div class='grid-container'> |
| <div class='cell'> |
| <div class="annotation">Latest release</div> |
| <h1>Apache NetBeans 28</h1> |
| <p><a class="button success" href="../../../../../../front/main/download/nb28">Download</a></p> |
| </div> |
| </div> |
| </section> |
| <div class='grid-container main-content tutorial'> |
| <article class="doc"> |
| <h1 class="sect0">Applying @Alternative Beans and Lifecycle Annotations</h1> |
| <div class="sectionbody"> |
| <div class="admonitionblock note"> |
| <table> |
| <tbody><tr> |
| <td class="icon"><i class="fa icon-note" title="Note"></i></td> |
| <td class="content">This tutorial needs a review. |
| You can <a href="https://github.com/apache/netbeans-antora-tutorials/edit/main/modules/ROOT/pages/kb/docs/javaee/cdi-validate.adoc" title="Edit this tutorial in github">edit it in GitHub </a> |
| following these <a href="../../../../../../tutorial/main/kb/docs/contributing">contribution guidelines.</a></td> |
| </tr></tbody> |
| </table> |
| </div> |
| </div> |
| <div id="toc" class="toc"> |
| <div id="toctitle"></div> |
| <ul class="sectlevel1"> |
| <li><a href="#_contexts_and_dependency_injection">Contexts and Dependency Injection</a></li> |
| <li><a href="#alternative">Handling Multiple Deployments</a></li> |
| <li><a href="#lifecycle">Applying Lifecycle Annotations to Managed Beans</a></li> |
| <li><a href="#seealso">See Also</a></li> |
| </ul> |
| </div> |
| <div id="preamble"> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p><em>Contributed by Andy Gibson</em></p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_contexts_and_dependency_injection"><a class="anchor" href="#_contexts_and_dependency_injection"></a>Contexts and Dependency Injection</h2> |
| <div class="sectionbody"> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p><a href="../cdi-intro/" class="xref page">Getting Started with CDI and JSF 2.0</a></p> |
| </li> |
| <li> |
| <p><a href="../cdi-inject/" class="xref page">Working with Injection and Qualifiers in CDI</a></p> |
| </li> |
| <li> |
| <p><strong>Applying @Alternative Beans and Lifecycle Annotations</strong></p> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="#alternative">Handling Multiple Deployments</a></p> |
| </li> |
| <li> |
| <p><a href="#lifecycle">Applying Lifecycle Annotations to Managed Beans</a></p> |
| </li> |
| <li> |
| <p><a href="#seealso">See Also</a></p> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p><a href="../cdi-events/" class="xref page">Working with Events in CDI</a></p> |
| </li> |
| </ol> |
| </div> |
| </li> |
| </ul> |
| </div> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <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> |
| </div> |
| <div class="paragraph"> |
| <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 take advantage of the <code>@Alternative</code> annotation to configure your application for different deployments, and also shows how you can use managed bean lifecycle annotations, such as <code>@PostConstruct</code> and <code>@PreDestroy</code>, to combine CDI injection with functionality provided by the <a href="http://jcp.org/en/jsr/detail?id=316">Java EE 6 Managed Bean Specification</a>.</p> |
| </div> |
| <div class="paragraph"> |
| <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> |
| </div> |
| <div class="paragraph"> |
| <p>To complete this tutorial, you need the following software and resources.</p> |
| </div> |
| <table class="tableblock frame-all grid-all stretch"> |
| <colgroup> |
| <col style="width: 50%;"> |
| <col style="width: 50%;"> |
| </colgroup> |
| <thead> |
| <tr> |
| <th class="tableblock halign-left valign-top">Software or Resource</th> |
| <th class="tableblock halign-left valign-top">Version Required</th> |
| </tr> |
| </thead> |
| <tbody> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="../../../../../../front/main/download/" class="xref page">NetBeans IDE</a></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">7.2, 7.3, 7.4, 8.0, Java EE version</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java Development Kit (JDK)</a></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">version 7 or 8</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="http://glassfish.dev.java.net/">GlassFish server</a></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">Open Source Edition 3.x or 4.x</p></td> |
| </tr> |
| <tr> |
| <td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo2.zip">cdiDemo2.zip</a></p></td> |
| <td class="tableblock halign-left valign-top"><p class="tableblock">n/a</p></td> |
| </tr> |
| </tbody> |
| </table> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>The NetBeans IDE Java bundle also includes the GlassFish Server Open Source Edition which is a Java EE-compliant container.</p> |
| </li> |
| <li> |
| <p>The solution sample project for this tutorial can be downloaded: <a href="https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FcdiDemo3.zip">cdiDemo3.zip</a></p> |
| </li> |
| </ul> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="alternative"><a class="anchor" href="#alternative"></a>Handling Multiple Deployments</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>CDI offers the use of the <code>@Alternative</code> annotation which lets you package multiple beans that match an injection point without ambiguity errors. In other words, you can apply the <code>@Alternative</code> annotation to two or more beans, then, based on your deployment, specify the bean you want to use in CDI’s <code>beans.xml</code> configuration file.</p> |
| </div> |
| <div class="paragraph"> |
| <p>To demonstrate this, consider the following scenario. We inject an <code>ItemValidator</code> into our main <code>ItemProcessor</code> class. The <code>ItemValidator</code> is implemented by both <code>DefaultItemValidator</code> and <code>RelaxedItemValidator</code>. Based on our deployment requirements, we’d like to use <code>DefaultItemValidator</code> for most cases, but also require <code>RelaxedItemValidator</code> for a specific deployment. To resolve this, we annotate both beans, then specify which bean to use for a given deployment by adding an entry to the application’s <code>beans.xml</code> file.</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/cdi-diagram-alternative.png" alt="cdi diagram alternative"> |
| </div> |
| <div class="title">Figure 1. Use CDI injection to loosely couple classes in your application</div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Begin by extracting the sample start project from the <code>cdiDemo2.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.</p> |
| </li> |
| <li> |
| <p>Right-click the project node in the Projects window and choose Properties.</p> |
| </li> |
| <li> |
| <p>Select the Run category and confirm that your GlassFish instance is selected in the Server dropdown list.</p> |
| </li> |
| <li> |
| <p>Create an <code>ItemValidator</code> interface.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>Click the New File ( images:./new-file-btn.png[] ) button or press Ctrl-N (⌘-N on Mac) to open the File wizard.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Select the Java category, then select Java Interface. Click Next.</p> |
| </li> |
| <li> |
| <p>Type in <strong>ItemValidator</strong> as the class name, then enter <strong>exercise3</strong> as the package.</p> |
| </li> |
| <li> |
| <p>Click Finish. The new interface is generated and opens in the editor.</p> |
| </li> |
| <li> |
| <p>Add a method called <code>isValid()</code> that takes an <code>Item</code> object and returns a <code>boolean</code> value.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface ItemValidator { |
| *boolean isValid(Item item);* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise2.Item</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Expand the <code>ItemProcessor</code> class to incorporate the new feature. Open <code>ItemProcessor</code> in the editor and make the following changes.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Named |
| @RequestScoped |
| public class ItemProcessor { |
| |
| @Inject @Demo |
| private ItemDao itemDao; |
| |
| *@Inject |
| private ItemValidator itemValidator;* |
| |
| public void execute() { |
| List<Item> items = itemDao.fetchItems(); |
| for (Item item : items) { |
| System.out.println(*"Item = " + item + " valid = " + itemValidator.isValid(item)*); |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Use the editor’s hint to add the import statement for <code>exercise3.ItemValidator</code>.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Create an implementation of <code>ItemValidator</code> named <code>DefaultItemValidator</code> that simply tests the limit against the value.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>In the Projects window, right-click the <code>exercise3</code> package and choose New > Java Class. Name the class <strong>DefaultItemValidator</strong> and click Finish.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Have <code>DefaultItemValidator</code> implement <code>ItemValidator</code> and override the <code>isValid()</code> method as follows.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class DefaultItemValidator *implements ItemValidator* { |
| |
| *@Override |
| public boolean isValid(Item item) { |
| return item.getValue() < item.getLimit(); |
| }* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise2.Item</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Click the Run Project ( images:./run-project-btn.png[] ) button in the IDE’s main toolbar. The project is compiled and deployed to GlassFish, and the application’s welcome page (<code>process.xhtml</code>) opens in the browser.</p> |
| </li> |
| <li> |
| <p>Click the ‘Execute’ 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 tab. You can see that items are being validated, and the only valid item listed is the case where the value is less than the limit.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">INFO: Item = exercise2.Item@e857ac [Value=34, Limit=7] valid = false |
| INFO: Item = exercise2.Item@63124f52 [Value=4, Limit=37] valid = true |
| INFO: Item = exercise2.Item@4715c34e [Value=24, Limit=19] valid = false |
| INFO: Item = exercise2.Item@65c95a57 [Value=89, Limit=32] valid = false</code></pre> |
| </div> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/output-window.png" alt="output window"> |
| </div> |
| <div class="title">Figure 2. View the server log in the Output window</div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Now consider a scenario where you have to deploy to a different site that is more relaxed and considers an item invalid only if the value is more than twice the limit. You may want to have another bean that implements the <code>ItemValidator</code> interface for that logic.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>Create a new implementation of <code>ItemValidator</code> named <code>RelaxedItemValidator</code>. In the Projects window, right-click the <code>exercise3</code> package and choose New > Java Class. Name the class <strong>RelaxedItemValidator</strong> and click Finish.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Have <code>RelaxedItemValidator</code> implement <code>ItemValidator</code> and override the <code>isValid()</code> method as follows.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class RelaxedItemValidator *implements ItemValidator* { |
| |
| *@Override |
| public boolean isValid(Item item) { |
| return item.getValue() < (item.getLimit() * 2); |
| }* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise2.Item</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Click the Run Project ( images:./run-project-btn.png[] ) button to run the project. Note that the project now fails to deploy.</p> |
| </li> |
| <li> |
| <p>Examine the server log in the Output window (Ctrl-4; ⌘-4 on Mac). You see an error message reporting an 'ambiguous dependency' problem. This occurs because you now have two classes implementing the same interface.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">org.glassfish.deployment.common.DeploymentException: Injection point has ambiguous dependencies. |
| Injection point: field exercise2.ItemProcessor.itemValidator; |
| Qualifiers: [@javax.enterprise.inject.Default()]; |
| Possible dependencies: [exercise3.RelaxedItemValidator, exercise3.DefaultItemValidator]</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Weld, the implementation for CDI, cannot determine whether to use <code>RelaxedItemValidator</code> or <code>DefaultItemValidator</code> for the given injection point.</p> |
| </div> |
| <div class="paragraph"> |
| <p>As mentioned, the only difference is based on deployment. For most deployments, you want to use the default validator, but for one deployment you want to use the 'relaxed' implementation. CDI offers the use of the <code>@Alternative</code> annotation which lets you package multiple beans that match an injection point without ambiguity errors, and the bean to use is defined in the <code>beans.xml</code>. This allows you to deploy both implementations in the same module with the only difference being the <code>beans.xml</code> definition, which can change over different deployments.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add the <code>@Alternative</code> annotation and corresponding import statement to <code>RelaxedItemValidator</code> and <code>DefaultItemValidator</code>.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>Open <code>RelaxedItemValidator</code> in the editor and make the following change.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">*import javax.enterprise.inject.Alternative;* |
| ... |
| |
| *@Alternative* |
| public class RelaxedItemValidator implements ItemValidator { |
| |
| public boolean isValid(Item item) { |
| return item.getValue() < (item.getLimit() * 2); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Type ‘@Al’ then press Ctrl-Space to invoke code completion. Because only one option is filtered, the <code>@Alternative</code> annotation is completed, and the corresponding import statement for <code>javax.enterprise.inject.Alternative</code> is automatically added to the top of the file. Typically, pressing Ctrl-Space on annotations also provides a Javadoc documentation popup.</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/code-completion-alternative.png" alt="code completion alternative"> |
| </div> |
| <div class="title">Figure 3. Press Ctrl-Space on annotations to invoke Javadoc documentation</div> |
| </div> |
| <div class="paragraph"> |
| <p>Switch to <code>DefaultItemValidator</code> (press Ctrl-Tab) and make the following change.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">*import javax.enterprise.inject.Alternative;* |
| ... |
| |
| *@Alternative* |
| public class DefaultItemValidator implements ItemValidator { |
| |
| public boolean isValid(Item item) { |
| return item.getValue() < item.getLimit(); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If you deployed the application now you would get an 'unsatisfied dependency' error since you defined the two matching beans as alternative but you did not enable either of them in the <code>beans.xml</code> file.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Use the IDE’s Go to File dialog to quickly open the <code>beans.xml</code> file. Choose Navigate > Go to File from the IDE’s main menu (Alt-Shift-O; Ctrl-Shift-O on Mac), then type ‘beans’. Click OK.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/go-to-file.png" alt="go to file"> |
| </div> |
| <div class="title">Figure 4. Use the Go to File dialog to quickly locate a project file</div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Make the following change to the <code>beans.xml</code> file.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-xml hljs" data-lang="xml"><beans xmlns="http://java.sun.com/xml/ns/javaee" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> |
| |
| *<alternatives> |
| <class>exercise3.RelaxedItemValidator</class> |
| </alternatives>* |
| |
| </beans></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>This tells CDI to use the <code>RelaxedItemValidator</code> for this deployment. You can think of the <code>@Alternative</code> annotation as effectively disabling the bean, making it unavailable for injection, but allowing the implementation to be packaged with the other beans. Adding it as an alternative in the <code>beans.xml</code> file effectively re-enables the bean, making it available for injection. By moving this type of metadata to the <code>beans.xml</code> file, we can bundle different versions of the file with different deployments.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Click the Run Project ( images:./run-project-btn.png[] ) button to run the project (Alternatively, press F6; fn-F6 on Mac). In the browser, click the ‘Execute’ button that displays on the page. Switch back to the IDE and examine the GlassFish server log displayed in the Output window (Ctrl-4; ⌘-4 on Mac).</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">INFO: Item = exercise2.Item@672f0924 [Value=34, Limit=7] valid = false |
| INFO: Item = exercise2.Item@41014f68 [Value=4, Limit=37] valid = true |
| INFO: Item = exercise2.Item@3d04562f [Value=24, Limit=19] valid = true |
| INFO: Item = exercise2.Item@67b646f4 [Value=89, Limit=32] valid = false</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>You can see that the <code>RelaxedItemValidator</code> implementation is being used, as the third item displays as valid while the provided value (<code>24</code>) is greater than the given limit (<code>19</code>).</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="lifecycle"><a class="anchor" href="#lifecycle"></a>Applying Lifecycle Annotations to Managed Beans</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>In this exercise, you inject an <code>ItemErrorHandler</code> into the main <code>ItemProcessor</code> class. Because <code>FileErrorReporter</code> is the only implementation of the <code>ItemErrorHandler</code> interface, it is selected for the injection. To set up lifecycle-specific actions for the class, you use the <code>@PostConstruct</code> and <code>@PreDestroy</code> annotations from the Managed Bean specification (included in <a href="http://jcp.org/en/jsr/detail?id=316">JSR 316: Java Platform, Enterprise Edition 6 Specification</a>).</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/cdi-diagram-lifecycle.png" alt="cdi diagram lifecycle"> |
| </div> |
| <div class="title">Figure 5. Use CDI injection to loosely couple classes in your application</div> |
| </div> |
| <div class="paragraph"> |
| <p>Continuing with the example, create an <code>ItemErrorHandler</code> interface to handle invalid items when they are discovered.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>In the Projects window, right-click the <code>exercise3</code> package and choose New > Java Interface.</p> |
| </li> |
| <li> |
| <p>In the Java Interface wizard, type in <strong>ItemErrorHandler</strong> as the class name, then enter <strong>exercise3</strong> as the package. Click Finish.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>The new interface is generated and opens in the editor.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add a method called <code>handleItem()</code> that takes an <code>Item</code> object as an argument.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public interface ItemErrorHandler { |
| *void handleItem(Item item);* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise2.Item</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Begin by implementing the <code>ItemErrorHandler</code> with a bogus handler named <code>FileErrorReporter</code> that saves item details to a file.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="paragraph"> |
| <p>In the Projects window, right-click the <code>exercise3</code> package and choose New > Java Class. Name the class <strong>FileErrorReporter</strong> and click Finish.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Have <code>FileErrorReporter</code> implement <code>ItemErrorHandler</code> and override the <code>handleItem()</code> method as follows.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class FileErrorReporter *implements ItemErrorHandler* { |
| |
| *@Override |
| public void handleItem(Item item) { |
| System.out.println("Saving " + item + " to file"); |
| }* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise2.Item</code>.)</p> |
| </div> |
| <div class="paragraph"> |
| <p>You want to open the file before you start handling items, leave it open for the duration of the process as content is added to the file, and then close the file when we the processing is done. You could manually add <code>initProcess()</code> and <code>finishProcess()</code> methods to the error reporter bean, but then you could not code to the interface since the caller would need to know about those class specific methods. You could add those same methods to the <code>ItemErrorReporter</code> interface but then you would have to unnecessarily implement those methods in every class that implements that interface. Instead, you can use some of the lifecycle annotations from the Managed Bean specification (included in <a href="http://jcp.org/en/jsr/detail?id=316">JSR 316: Java Platform, Enterprise Edition 6 Specification</a>) to call methods on the bean at certain points in the bean lifecycle. A <code>@PostConstruct</code> annotated method is called when the bean has been constructed and any dependencies the bean has have been injected. Likewise, a <code>@PreDestroy</code> annotated method is called just before the bean is disposed of by the container.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add the following <code>init()</code> and <code>release()</code> methods with corresponding <code>@PostConstruct</code> and <code>@PreDestroy</code> annotations.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">public class FileErrorReporter implements ItemErrorHandler { |
| |
| *@PostConstruct |
| public void init() { |
| System.out.println("Creating file error reporter"); |
| } |
| |
| @PreDestroy |
| public void release() { |
| System.out.println("Closing file error reporter"); |
| }* |
| |
| @Override |
| public void handleItem(Item item) { |
| System.out.println("Saving " + item + " to file"); |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Fix imports. Either right-click in the editor and choose Fix Imports, or press Ctrl-Shift-I (⌘-Shift-I on Mac). Import statements for <code>javax.annotation.PostConstruct</code> and <code>javax.annotation.PreDestroy</code> are added to the top of the file.</p> |
| </li> |
| <li> |
| <p>Finally, add the new <code>ItemErrorHandler</code> bean to the <code>ItemProcessor</code>.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Named |
| @RequestScoped |
| public class ItemProcessor { |
| |
| @Inject @Demo |
| private ItemDao itemDao; |
| |
| @Inject |
| private ItemValidator itemValidator; |
| |
| *@Inject |
| private ItemErrorHandler itemErrorHandler;* |
| |
| public void execute() { |
| List<Item> items = itemDao.fetchItems(); |
| for (Item item : items) { |
| *if (!itemValidator.isValid(item)) { |
| itemErrorHandler.handleItem(item); |
| }* |
| } |
| } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add the import statement for <code>exercise3.ItemErrorHandler</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Click the Run Project ( images:./run-project-btn.png[] ) button to run the project (Alternatively, press F6; fn-F6 on Mac). In the browser, click the ‘Execute’ button that displays on the page. Switch back to the IDE and examine the GlassFish server log displayed in the Output window (Ctrl-4; ⌘-4 on Mac).</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">INFO: Creating file error reporter |
| INFO: Saving exercise2.Item@6257d812 [Value=34, Limit=7] to file |
| INFO: Saving exercise2.Item@752ab82e [Value=89, Limit=32] to file |
| INFO: Closing file error reporter</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><a href="../../../../../../front/main/community/mailing-lists/" class="xref page">Send Feedback on This Tutorial</a></p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="seealso"><a class="anchor" href="#seealso"></a>See Also</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Different application deployments might use different rules for handling invalid items, such as rejecting an item, sending notifications to individuals, flagging them, or just listing them in an output file. In addition, we may want to do a combination of these (e.g., reject an order, send an email to a sales representative, and list the order in a file). One great way to handle this kind of multi-faceted problem is by using <em>events</em>. CDI events are the subject of the final installment of this series:</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="../cdi-events/" class="xref page">Working with Events in CDI</a></p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>For more information about CDI and Java EE, see the following resources.</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="../cdi-intro/" class="xref page">Getting Started with Contexts and Dependency Injection and JSF 2.0</a></p> |
| </li> |
| <li> |
| <p><a href="../cdi-inject/" class="xref page">Working with Injection and Qualifiers in CDI</a></p> |
| </li> |
| <li> |
| <p><a href="../javaee-gettingstarted/" class="xref page">Getting Started with Java EE Applications</a></p> |
| </li> |
| <li> |
| <p><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></p> |
| </li> |
| <li> |
| <p><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></p> |
| </li> |
| <li> |
| <p><a href="http://jcp.org/en/jsr/detail?id=299">JSR 299: Specification for Contexts and Dependency Injection</a></p> |
| </li> |
| <li> |
| <p><a href="http://jcp.org/en/jsr/detail?id=316">JSR 316: Java Platform, Enterprise Edition 6 Specification</a></p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| <section class='tools'> |
| <ul class="menu align-center"> |
| <li><a title="Facebook" href="https://www.facebook.com/NetBeans"><i class="fa fa-md fa-facebook"></i></a></li> |
| <li><a title="Twitter" href="https://twitter.com/netbeans"><i class="fa fa-md fa-twitter"></i></a></li> |
| <li><a title="Github" href="https://github.com/apache/netbeans"><i class="fa fa-md fa-github"></i></a></li> |
| <li><a title="YouTube" href="https://www.youtube.com/user/netbeansvideos"><i class="fa fa-md fa-youtube"></i></a></li> |
| <li><a title="Atom Feed" href="https://netbeans.apache.org/blogs/atom"><i class="fa fa-mf fa-rss"></i></a></li> |
| <li><a title="Slack" href="https://tinyurl.com/netbeans-slack-signup/"><i class="fa fa-md fa-slack"></i></a></li> |
| <li><a title="Issues" href="https://github.com/apache/netbeans/issues"><i class="fa fa-mf fa-bug"></i></a></li> |
| </ul> |
| <ul class="menu align-center"> |
| <li><a href="https://github.com/apache/netbeans-antora-tutorials/edit/main/modules/ROOT/pages/kb/docs/javaee/cdi-validate.adoc" title="See this page in github"><i class="fa fa-md fa-edit"></i> See this page in GitHub.</a></li> |
| </ul> |
| </section> |
| </article> |
| </div> |
| <div class='grid-container incubator-area' style='margin-top: 64px'> |
| <div class='grid-x grid-padding-x'> |
| <div class='large-auto cell text-center'> |
| <a href="https://www.apache.org/"> |
| <img style="height: 60px" title="Apache Software Foundation" src="../../../../../../_/images/asf_logo_wide.svg" /> |
| </a> |
| </div> |
| <div class='large-auto cell text-center'> |
| <a href="https://www.apache.org/events/current-event.html"> |
| <img style="width:234px; height: 60px;" title="Apache Software Foundation current event" src="https://www.apache.org/events/current-event-234x60.png"/> |
| </a> |
| </div> |
| </div> |
| </div> |
| <footer> |
| <div class="grid-container"> |
| <div class="grid-x grid-padding-x"> |
| <div class="large-auto cell"> |
| <h1><a href="../../../../../../front/main/about">About</a></h1> |
| <ul> |
| <li><a href="../../../../../../front/main/community/who">Who's Who</a></li> |
| <li><a href="https://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| <li><a href="https://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> |
| <li><a href="https://www.apache.org/security/">Security</a></li> |
| </ul> |
| </div> |
| <div class="large-auto cell"> |
| <h1><a href="../../../../../../front/main/community">Community</a></h1> |
| <ul> |
| <li><a href="../../../../../../front/main/community/mailing-lists">Mailing lists</a></li> |
| <li><a href="../../../../../../front/main/community/committer">Becoming a committer</a></li> |
| <li><a href="../../../../../../front/main/community/events">NetBeans Events</a></li> |
| <li><a href="https://www.apache.org/events/current-event.html">Apache Events</a></li> |
| </ul> |
| </div> |
| <div class="large-auto cell"> |
| <h1><a href="../../../../../../front/main/participate">Participate</a></h1> |
| <ul> |
| <li><a href="../../../../../../front/main/participate/submit-pr">Submitting Pull Requests</a></li> |
| <li><a href="../../../../../../front/main/participate/report-issue">Reporting Issues</a></li> |
| <li><a href="../../../../../../front/main/participate/#documentation">Improving the documentation</a></li> |
| </ul> |
| </div> |
| <div class="large-auto cell"> |
| <h1><a href="../../../../../../front/main/help">Get Help</a></h1> |
| <ul> |
| <li><a href="../../../../../../front/main/help/#documentation">Documentation</a></li> |
| <li><a href="../../../../../../wiki/main/wiki">Wiki</a></li> |
| <li><a href="../../../../../../front/main/help/#support">Community Support</a></li> |
| <li><a href="../../../../../../front/main/help/commercial-support">Commercial Support</a></li> |
| </ul> |
| </div> |
| <div class="large-auto cell"> |
| <h1><a href="../../../../../../front/main/download">Download</a></h1> |
| <ul> |
| <li><a href="../../../../../../front/main/download">Releases</a></li> |
| <li><a href="https://plugins.netbeans.apache.org/">Plugins</a></li> |
| <li><a href="../../../../../../front/main/download/#_daily_builds_and_building_from_source">Building from source</a></li> |
| <li><a href="../../../../../../front/main/download/#_older_releases">Previous releases</a></li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </footer> |
| <div class='footer-disclaimer'> |
| <div class="footer-disclaimer-content"> |
| <p>Copyright © 2017-2025 <a href="https://www.apache.org">The Apache Software Foundation</a>.</p> |
| <p>Licensed under the Apache <a href="https://www.apache.org/licenses/">license</a>, version 2.0</p> |
| <div style='max-width: 40em; margin: 0 auto'> |
| <p>Apache, Apache NetBeans, NetBeans, the Apache feather logo and the Apache NetBeans logo are trademarks of <a href="https://www.apache.org">The Apache Software Foundation</a>.</p> |
| <p>Oracle and Java are registered trademarks of Oracle and/or its affiliates.</p> |
| <p>The Apache NetBeans website conforms to the <a href="https://privacy.apache.org/policies/privacy-policy-public.html">Apache Software Foundation Privacy Policy</a></p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <script src="../../../../../../_/js/vendor/lunr.js"></script> |
| <script src="../../../../../../_/js/search-ui.js" id="search-ui-script" data-site-root-path="../../../../../.." data-snippet-length="100" data-stylesheet="../../../../../../_/css/search.css"></script> |
| <script async src="../../../../../../search-index.js"></script> |
| <script src="../../../../../../_/js/vendor/jquery.min.js"></script> |
| <script src="../../../../../../_/js/vendor/what-input.min.js"></script> |
| <script src="../../../../../../_/js/vendor/foundation.min.js"></script> |
| <script src="../../../../../../_/js/vendor/jquery.colorbox-min.js"></script> |
| <script src="../../../../../../_/js/netbeans.js"></script> |
| <script> |
| $(function(){ $(document).foundation(); }); |
| </script> |
| <script src="../../../../../../_/js/vendor/highlight.min.js"></script> |
| <script> |
| document.addEventListener('DOMContentLoaded', (event) => { |
| document.querySelectorAll('pre code').forEach((el) => { |
| hljs.highlightElement(el); |
| }); |
| }); |
| </script> |
| </body> |
| </html> |