| <!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>Working with Events in CDI</title> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta name="description" content="Working with Events in CDI - Apache NetBeans"> |
| <meta name="author" content="Apache NetBeans"> |
| <meta name="description" content="Working with Events in CDI - Apache NetBeans"> |
| <meta name="keywords" content="Apache NetBeans, Tutorials, Working with Events in CDI"> |
| <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">Working with Events in CDI</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-events.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="#event">Utilizing Events</a></li> |
| <li><a href="#scopes">Handling Scopes</a></li> |
| <li><a href="#seealso">See Also</a> |
| <ul class="sectlevel2"> |
| <li><a href="#_netbeans_resources">NetBeans Resources</a></li> |
| <li><a href="#_external_resources">External Resources</a></li> |
| </ul> |
| </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> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p><a href="../cdi-inject/" class="xref page">Working with Injection and Qualifiers in CDI</a></p> |
| </li> |
| <li> |
| <p><a href="../cdi-validate/" class="xref page">Applying @Alternative Beans and Lifecycle Annotations</a></p> |
| </li> |
| <li> |
| <p><strong>Working with Events in CDI</strong></p> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><a href="#event">Utilizing Events</a></p> |
| </li> |
| <li> |
| <p><a href="#scopes">Handling Scopes</a></p> |
| </li> |
| <li> |
| <p><a href="#seealso">See Also</a></p> |
| </li> |
| </ul> |
| </div> |
| </li> |
| </ol> |
| </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/2010/01/11/getting-started-with-jsf-2-0-and-cdi-part-3/">Getting Started with CDI part 3 – Events</a>. It demonstrates how to take advantage of the Java EE concept of <em>events</em>, in which you produce and subscribe to (i.e., <em>observe</em>) events occuring in your application in a way that enables you to maintain decoupled code between producers and observers. You use the <code>javax.enterprise.event.Event</code> class to create events, and CDI’s <code>@Observes</code> annotation to subscribe to events.</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%252FcdiDemo3.zip">cdiDemo3.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 EE 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%252FcdiDemoComplete.zip">cdiDemoComplete.zip</a></p> |
| </li> |
| </ul> |
| </div> |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="event"><a class="anchor" href="#event"></a>Utilizing Events</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>In the previous tutorial, <a href="../cdi-validate/" class="xref page">Applying @Alternative Beans and Lifecycle Annotations</a>, we had an application that obtained a list of items, validated them and took a specific action when an invalid item was found. Let’s say in the future we want to expand our system to handle all sorts of things happening when we find an invalid item. This could range from an email being sent, changes made to other data such as an order being canceled, or storing a list of rejections in a file or database table. To completely decouple the implementation we can use <em>events</em> in Java EE. Events are raised by the event <em>producer</em> and subscribed to by event <em>observers</em>. Like most of CDI, event production and subscription is type-safe and allows qualifiers to determine which events observers will be observing.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Using the application we’ve been building from the previous tutorials in the series, we don’t require many changes to implement this. We can just provide another implementation of <code>ItemErrorHandler</code> (created in <a href="../cdi-validate/" class="xref page">the previous tutorial</a>), which raises an event each time it handles an item. We’ll name this class <code>EventItemHandler</code>, inject it into the <code>ItemProcessor</code>, and use a <code>Notify</code> qualifier to select it for injection.</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/cdi-diagram-events.png" alt="cdi diagram events"> |
| </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>cdiDemo3.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>Create a class named <code>EventItemHandler</code>. Click the New File ( images:./new-file-btn.png[] ) button or press Ctrl-N (⌘-N on Mac) to open the File wizard.</p> |
| </li> |
| <li> |
| <p>Select the Java category, then select Java Class. Click Next.</p> |
| </li> |
| <li> |
| <p>Type in <strong>EventItemHandler</strong> as the class name, then enter <strong>exercise4</strong> as the package.</p> |
| </li> |
| <li> |
| <p>Click Finish. The new class and package are generated, and the class opens in the editor.</p> |
| </li> |
| <li> |
| <p>Implement <strong>EventItemHandler</strong> 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 EventItemHandler *implements ItemErrorHandler* { |
| |
| *@Inject |
| private Event<Item> itemEvent; |
| |
| @Override |
| public void handleItem(Item item) { |
| System.out.println("Firing Event"); |
| itemEvent.fire(item); |
| }* |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>We inject an instance of an <code>Event</code> where the event payload will be an <code>Item</code>. The event payload is the state data passed from the event producer to the event observer which in this case passes the rejected Item. When the invalid item is handled, we fire the event and pass in the invalid item we received. This event based item handler is injected the same as any other item handler would be so we can swap it in and out whenever we need to and also can substitute it during testing.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Fix all imports. Either right-click in the editor and choose Fix Imports, or press Ctrl-Shift-I (⌘-Shift-I on Mac). Be sure to select <code>javax.enterprise.event.Event</code> as the fully qualified name to the <code>Event</code> class.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/fix-all-imports.png" alt="fix all imports"> |
| </div> |
| <div class="title">Figure 2. Right-click in the editor and choose Fix Imports to invoke the Fix Imports dialog</div> |
| </div> |
| <div class="admonitionblock tip"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-tip" title="Tip"></i> |
| </td> |
| <td class="content"> |
| Press Ctrl-Space on <code>Event</code> to view the Javadoc definition of the class. The <code>fire()</code> method, used above, is also defined.# |
| </td> |
| </tr> |
| </table> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/event-javadoc.png" alt="event javadoc"> |
| </div> |
| <div class="title">Figure 3. Press Ctrl-Space to view Javadoc documentation on classes in the API</div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Create a qualifier named <code>Notify</code>. (Qualifiers were discussed in <a href="../cdi-inject/" class="xref page">Working with Injection and Qualifiers in CDI</a>.)</p> |
| </li> |
| <li> |
| <p>Click the New File ( images:./new-file-btn.png[] ) button or press Ctrl-N (⌘-N on Mac) to open the File wizard.</p> |
| </li> |
| <li> |
| <p>Select the Context and Dependency Injection category, then select Qualifier Type. Click Next.</p> |
| </li> |
| <li> |
| <p>Enter <strong>Notify</strong> as the class name, then enter <strong>exercise4</strong> as the package.</p> |
| </li> |
| <li> |
| <p>Click Finish. The new <code>Notify</code> qualifier opens in the editor.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Qualifier |
| @Retention(RUNTIME) |
| @Target({METHOD, FIELD, PARAMETER, TYPE}) |
| public @interface Notify { |
| }</code></pre> |
| </div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add the <code>@Notify</code> annotation to <code>EventItemHandler</code>.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">*@Notify* |
| public class EventItemHandler implements ItemErrorHandler { |
| |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>We created a <code>@Notify</code> qualifier annotation to identify this error handler for injection and can use it in our <code>ItemProcessor</code> by adding it to the injection point.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add the <code>@Notify</code> annotation to <code>EventItemHandler’s injection point in `exercise2.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 *@Notify* |
| 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>exercise4.Notify</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.</p> |
| </li> |
| <li> |
| <p>In the browser, click the ‘Execute’ button, then return to the IDE and examine the server log in the Output window (Ctrl-4; ⌘-4 on Mac). Because the application that you have been building currently uses the <code>DefaultItemDao</code> to set up four <code>Item`s, then applies the `RelaxedItemValidator</code> on the <code>Item`s, you expect to see the `itemErrorHandler</code> fire twice.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/output-window.png" alt="output window"> |
| </div> |
| <div class="title">Figure 4. View the GlassFish server log displayed in Output window</div> |
| </div> |
| <div class="paragraph"> |
| <p>Currently though, we don’t have anything observing the event. We can fix this by creating an <em>observer</em> method using the <code>@Observes</code> annotation. This is the only thing needed to observe an event. To demonstrate, we can modify the <code>FileErrorReporter</code> (created in the <a href="../cdi-validate/" class="xref page">previous tutorial</a>) to respond to fired events by adding an observer method that calls its <code>handleItem()</code> method.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>To make our <code>FileErrorReporter</code> respond to the event, add the following method to the class.</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 { |
| |
| *public void eventFired(@Observes Item item) { |
| handleItem(item); |
| }* |
| |
| ... |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>(Use the editor’s hint to add an import statement for <code>javax.enterprise.event.Observes</code>.)</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Run the project (F6; fn-F6 on Mac) again, click the ‘Execute’ button, then return to the IDE and examine the server log in the Output window.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/output-window2.png" alt="output window2"> |
| </div> |
| <div class="title">Figure 5. View the GlassFish server log displayed in Output window</div> |
| </div> |
| <div class="paragraph"> |
| <p>You see that the events are fired on the invalid objects as they were previously, but now the item information is being saved when each event is fired. You can also note that the lifecycle events are being observed, since a <code>FileErrorReporter</code> bean is created and closed for each fired event. (See <a href="../cdi-validate/" class="xref page">Applying @Alternative Beans and Lifecycle Annotations</a> for a discussion of lifecycle annotations, e.g., <code>@PostConstruct</code> and <code>@PreDestroy</code>.)</p> |
| </div> |
| <div class="paragraph"> |
| <p>As shown in the above steps, the <code>@Observes</code> annotation provides an easy way to observe an event.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Events and observers can also be annotated with qualifiers to enable observers to only observe specific events for an item. See <a href="http://www.andygibson.net/blog/index.php/2010/01/11/getting-started-with-jsf-2-0-and-cdi-part-3/">Getting Started with CDI part 3 – Events</a> for a demonstration.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="scopes"><a class="anchor" href="#scopes"></a>Handling Scopes</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>In the present state of the application, a <code>FileErrorReporter</code> bean is created each time the event is raised. In this case, we don’t want to create a new bean each time since we don’t want to open and close the file for each item. We still want to open the file at the start of the process, and then close it once the process it completed. Therefore, we need to consider the <em>scope</em> of the <code>FileErrorReporter</code> bean.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Currently, the <code>FileErrorReporter</code> bean doesn’t have a scope defined. When no scope is defined, CDI uses the default pseudo-dependent scope. What this means in practice is that the bean is created and destroyed over a very short space of time, typically over a method call. In our present scenario, the bean is created and destroyed for the duration of the event being fired. To fix this, we can lengthen the bean’s scope by manually adding a scope annotation. We’ll make this bean <code>@RequestScoped</code> so when the bean is created with the first event being fired, it will continue to exist for the duration of the request. This also means that for any injection points that this bean is qualified to be injected to, the same bean instance will be injected.</p> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Add the <code>@RequestScope</code> annotation and corresponding import statement for <code>javax.enterprise.context.RequestScoped</code> to the <code>FileErrorReporter</code> class.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">*import javax.enterprise.context.RequestScoped;* |
| ... |
| |
| *@RequestScoped* |
| public class FileErrorReporter implements ItemErrorHandler { ... }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><span class="tips">Press Ctrl-Space while you type in order to invoke the editor’s code completion support. When choosing an item through code completion, any associated import statements are automatically added to the class.</span></p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/code-completion.png" alt="code completion"> |
| </div> |
| <div class="title">Figure 6. Press Ctrl-Space when typing to invoke code completion suggestions</div> |
| </div> |
| <div class="olist arabic"> |
| <ol class="arabic"> |
| <li> |
| <p>Run the project (F6; fn-F6 on Mac) again, click the ‘Execute’ button, then return to the IDE and examine the server log in the Output window.</p> |
| </li> |
| </ol> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="../../../../_images/kb/docs/javaee/output-window3.png" alt="output window3"> |
| </div> |
| <div class="title">Figure 7. View the GlassFish server log displayed in Output window</div> |
| </div> |
| <div class="paragraph"> |
| <p>Note that the <code>FileErrorReporter</code> bean is only created when the first event is fired, and is closed after the final event has been fired.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">INFO: Firing Event |
| *INFO: Creating file error reporter* |
| INFO: Saving exercise2.Item@48ce88f6 [Value=34, Limit=7] to file |
| INFO: Firing Event |
| INFO: Saving exercise2.Item@3cae5788 [Value=89, Limit=32] to file |
| *INFO: Closing file error reporter*</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Events are a great way to decouple parts of the system in a modular fashion, as event observers and producers know nothing about each other, nor do they require any configuration for them to do so. You can add pieces of code that subscribe to events with the event producer unaware of the observer. (Without using events, you would typically need to have the event producer call the observer manually.) For example, if someone updates an order status, you could add events to email the sales representative, or notify an account manager if a tech support issue is open for more than a week. These kinds of rules can be implemented without events, but events make it easier to decouple the business logic. Additionally, there is no compile or build time dependency. You can just add modules to your application and they will automatically start observing and producing events.</p> |
| </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>For more information about CDI and Java EE, see the following resources.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_netbeans_resources"><a class="anchor" href="#_netbeans_resources"></a>NetBeans Resources</h3> |
| <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="../cdi-validate/" class="xref page">Applying @Alternative Beans and Lifecycle Annotations</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="../../web/jsf20-intro/" class="xref page">Introduction to JavaServer Faces 2.0</a></p> |
| </li> |
| </ul> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_external_resources"><a class="anchor" href="#_external_resources"></a>External Resources</h3> |
| <div class="ulist"> |
| <ul> |
| <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> |
| </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-events.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> |