[weld-commits] Weld SVN: r4729 - doc/trunk/reference/en-US.
weld-commits at lists.jboss.org
weld-commits at lists.jboss.org
Sat Nov 7 10:49:23 EST 2009
Author: gavin.king at jboss.com
Date: 2009-11-07 10:49:22 -0500 (Sat, 07 Nov 2009)
New Revision: 4729
Modified:
doc/trunk/reference/en-US/environments.xml
doc/trunk/reference/en-US/example.xml
doc/trunk/reference/en-US/gettingstarted.xml
doc/trunk/reference/en-US/injection.xml
doc/trunk/reference/en-US/intro.xml
doc/trunk/reference/en-US/producermethods.xml
Log:
lots of revisions
Modified: doc/trunk/reference/en-US/environments.xml
===================================================================
--- doc/trunk/reference/en-US/environments.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/environments.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -14,15 +14,15 @@
<para>
If you are using JBoss AS < 5.2, then you'll need to install Weld as an add-on. Fortunately, the
distribution has a build that can handle this for you in a single command. First, we need to tell Weld where
- JBoss AS is located. Create a new file named local.build.properties in the examples directory of the Weld
- distribution and assign the path of your JBoss AS installation to the property key
+ JBoss AS is located. Create a new file named <literal>local.build.properties</literal> in the examples directory
+ of the Weld distribution and assign the path of your JBoss AS installation to the property key
<literal>jboss.home</literal>, as follows:
</para>
<programlisting><![CDATA[jboss.home=/path/to/jboss-as-5.x]]></programlisting>
<para>
- Now we can install the Weld deployer from the jboss-as directory of the Weld distribution:
+ Now we can install the Weld deployer from the <literal>jboss-as</literal> directory of the Weld distribution:
</para>
<programlisting>$> cd jboss-as
@@ -58,15 +58,15 @@
<title>Servlet containers (such as Tomcat or Jetty)</title>
<para>
- While JSR-299 does not require support for Servlet environments, Weld can be used in any Servlet container,
+ While JSR-299 does not require support for servlet environments, Weld can be used in any servlet container,
such as Tomcat 6.0 or Jetty 6.1.
</para>
<note>
<para>
- There is a major limitation to using a Servlet container. Weld doesn't support deploying session beans,
+ There is a major limitation to using a servlet container. Weld doesn't support deploying session beans,
injection using <literal>@EJB</literal> or <literal>@PersistenceContext</literal>, or using transactional
- events in Servlet containers. For enterprise features such as these, you should really be looking at a Java
+ events in servlet containers. For enterprise features such as these, you should really be looking at a Java
EE application server.
</para>
</note>
@@ -75,7 +75,7 @@
Weld should be used as a web application library in a servlet container. You should place
<literal>weld-servlet.jar</literal> in <literal>WEB-INF/lib</literal> in the web root.
<literal>weld-servlet.jar</literal> is an "uber-jar", meaning it bundles all the bits of Weld and CDI required
- for running in a Servlet container, provided for your convenience: Alternatively, you could use its component
+ for running in a servlet container, provided for your convenience. Alternatively, you could use its component
jars:
</para>
Modified: doc/trunk/reference/en-US/example.xml
===================================================================
--- doc/trunk/reference/en-US/example.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/example.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -4,7 +4,7 @@
<title>JSF web application example</title>
<para>
- Let's illustrate these ideas with a full example. We're going to implement a user login/logout for an application
+ Let's illustrate these ideas with a full example. We're going to implement user login/logout for an application
that uses JSF. First, we'll define a request-scoped bean to hold the username and password entered during login:
</para>
@@ -88,14 +88,14 @@
public @interface UserDatabase {}]]></programlisting>
<para>
- We need an adapter bean to expose our typesafe <literal>EntityManager</literal>:
+ We need an adaptor bean to expose our typesafe <literal>EntityManager</literal>:
</para>
<programlisting role="JAVA"><![CDATA[public class UserDatabaseProducer {
@Produces @UserDatabase @PersistenceContext EntityManager userDatabase;
}]]></programlisting>
- <para>Now, any other bean can easily inject the current user, as well as other beans:</para>
+ <para>Now <literal>DocumentEditor</literal>, or any other bean, can easily inject the current user:</para>
<programlisting role="JAVA"><![CDATA[public class DocumentEditor {
@Inject Document document;
@@ -115,7 +115,7 @@
</h:panelGroup>]]></programlisting>
<para>
- Hopefully, this example gives a flavor of the CDI services. In the next chapter, we'll explore examples from the
+ Hopefully, this example gives a flavor of the CDI services. In the next chapter, we'll explore examples from the
CDI reference implementation, Weld, in greater depth.
</para>
Modified: doc/trunk/reference/en-US/gettingstarted.xml
===================================================================
--- doc/trunk/reference/en-US/gettingstarted.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/gettingstarted.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -2,10 +2,10 @@
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="gettingstarted">
- <title>Getting started Weld, the JSR-299 reference implementation</title>
+ <title>Getting started with Weld, the JSR-299 reference implementation</title>
<para>
- Weld, the JSR-299 RI (Reference Implementation), is being developed as part of the <ulink
+ Weld, the JSR-299 Reference Implementation (RI), is being developed as part of the <ulink
url="http://seamframework.org/Weld">Seam project</ulink>. You can download the latest community release of Weld
from the <ulink url="http://seamframework.org/Download">download page</ulink>. Information about the Weld source
code repository and instructions about how to obtain and build the source can be found on the same page.
@@ -16,13 +16,13 @@
<literal>weld-numberguess</literal>, is a web (WAR) example containing only non-transactional managed beans.
This example can be run on a wide range of servers, including JBoss AS, GlassFish, Apache Tomcat, Jetty, Google
App Engine, and any compliant Java EE 6 container. The second example, <literal>weld-translator</literal>, is
- an enterprise (EAR) example that contains session beans. This example must be run on JBoss AS 5.2 or any compliant
- Java EE 6 container.
+ an enterprise (EAR) example that contains session beans. This example must be run on JBoss AS 5.2, Glassfish 3.0
+ or any compliant Java EE 6 container.
</para>
<para>
- Both examples use JSF 2.0 as the web framework and, as such, can be found in the examples/jsf directory of the
- Weld distribution.
+ Both examples use JSF 2.0 as the web framework and, as such, can be found in the <literal>examples/jsf</literal>
+ directory of the Weld distribution.
</para>
<section id="prerequisites">
@@ -43,10 +43,10 @@
<para>a supported runtime environment (minimum versions shown)</para>
<itemizedlist>
<listitem>
- <para>JBoss AS 5.2.0 (currently only nightly builds of JBoss AS 5.2.0.Beta1 are available), or</para>
+ <para>JBoss AS 5.2.0 (currently only nightly builds of JBoss AS 5.2.0.Beta1 are available),</para>
</listitem>
<listitem>
- <para>GlassFish 3.0, or</para>
+ <para>GlassFish 3.0,</para>
</listitem>
<listitem>
<para>Apache Tomcat 6.0.x (WAR example only), or</para>
@@ -69,14 +69,15 @@
</note>
<para>
- In the next few sections, you'll be using the Ant command (ant) to invoke the Ant build script in each of the two
- examples to compile, assemble and deploy the example to JBoss AS and, for the WAR example, Apache Tomcat. You can
- also deploy the generated artifact (WAR or EAR) to any other container that supports Java EE 6, such as GlassFish V3.
+ In the next few sections, you'll be using the Ant command (<literal>ant</literal>) to invoke the Ant build script
+ in each example to compile, assemble and deploy the example to JBoss AS and, for the WAR example, Apache Tomcat.
+ You can also deploy the generated artifact (WAR or EAR) to any other container that supports Java EE 6, such as
+ GlassFish 3.
</para>
<para>
- If you have Maven installed, you can also use the Maven command (mvn) to compile and assemble the standalone
- artifact (WAR or EAR) and, for the WAR example, run it in an embedded container.
+ If you have Maven installed, you can use the Maven command (<literal>mvn</literal>) to compile and assemble the
+ standalone artifact (WAR or EAR) and, for the WAR example, run it in an embedded container.
</para>
<para>The sections below cover the steps for deploying with both Ant and Maven in detail. Let's start with JBoss AS.</para>
@@ -107,9 +108,9 @@
<para>
In order for the build scripts to know where to deploy the example, you have to tell them where to find your
- JBoss AS installation (i.e., <literal>JBOSS_HOME</literal>). Create a new file named local.build.properties in
- the examples directory of the Weld distribution and assign the path of your JBoss AS installation to the property
- key <literal>jboss.home</literal>, as follows:
+ JBoss AS installation (i.e., <literal>JBOSS_HOME</literal>). Create a new file named<literal>local.build.properties</literal>
+ in the examples directory of the Weld distribution and assign the path of your JBoss AS installation to the
+ property key <literal>jboss.home</literal>, as follows:
</para>
<programlisting><![CDATA[jboss.home=/path/to/jboss-as-5.2]]></programlisting>
@@ -119,7 +120,8 @@
</para>
<para>
- Switch to the examples/jsf/numberguess directory and execute the Ant deploy target:
+ Switch to the <literal>examples/jsf/numberguess</literal> directory and execute the Ant
+ <literal>deploy</literal> target:
</para>
<programlisting><![CDATA[$> cd examples/jsf/numberguess
@@ -159,7 +161,8 @@
<tip>
<para>
- The Ant build script includes additional targets for JBoss AS to deploy and undeploy the archive in either exploded or packaged format and to tidy things up.
+ The Ant build script includes additional targets for JBoss AS to deploy and undeploy the archive in either
+ exploded or packaged format and to tidy things up.
</para>
<itemizedlist>
<listitem>
@@ -202,13 +205,13 @@
<note>
<para>
The translator uses session beans, which are packaged in an EJB module within an EAR. Java EE 6 will allow
- session beans to be deployed in WAR modules, but that's a topic for future chapter.
+ session beans to be deployed in WAR modules, but that's a topic for a later chapter.
</para>
</note>
<para>
- Again, wait a few seconds for the application to deploy (if you are bored, read the log messages), and visit
- <ulink src="http://localhost:8080/weld-translator">http://localhost:8080/weld-translator</ulink> to begin
+ Again, wait a few seconds for the application to deploy (if you're really bored, read the log messages), and
+ visit <ulink src="http://localhost:8080/weld-translator">http://localhost:8080/weld-translator</ulink> to begin
pseudo-translating.
</para>
@@ -232,8 +235,9 @@
src="https://glassfish.dev.java.net/">GlassFish V3</ulink> release (the preview release won't do). If the final
release isn't yet available, you can download a <ulink
src="http://download.java.net/glassfish/v3/promoted/">promoted build</ulink> in the meantime. Select the b69
- preview release or above that ends in either -unix.sh or -windows.exe depending on your platform. After the
- download is complete, execute the installer. On Linux/Unix, you'll need to first make the script executable.
+ preview release or above that ends in either <literal>-unix.sh</literal> or <literal>-windows.exe</literal>
+ depending on your platform. After the download is complete, execute the installer. On Linux/Unix, you'll need
+ to first make the script executable.
</para>
<programlisting><![CDATA[$> chmod 755 glassfish-v3-b69-unix.sh
@@ -242,8 +246,8 @@
<para>
On Windows you can just click on the executable. Follow the instructions in the installer. It will create a
single domain named <literal>domain1</literal>. You'll use that domain to deploy the example. We recommend that
- you choose 7070 as the main HTTP port to avoid conflicts with a running instance of JBoss AS (or Apache
- Tomcat).
+ you choose <literal>7070</literal> as the main HTTP port to avoid conflicts with a running instance of JBoss AS
+ (or Apache Tomcat).
</para>
<para>
@@ -256,17 +260,17 @@
$> ant package]]></programlisting>
<para>
- The deployable archive for the <literal>weld-numberguess</literal>, named weld-numberguess.war, ends up in the
- example's target directory. The archive for the <literal>weld-translator</literal> example, named
- weld-translator.ear, ends up in the example's ear/target directory. All you need to do now is deploy them to
- GlassFish.
+ The deployable archive for the <literal>weld-numberguess</literal>, named <literal>weld-numberguess.war</literal>,
+ ends up in the example's <literal>target</literal> directory. The archive for the <literal>weld-translator</literal>
+ example, named <literal>weld-translator.ear</literal>, ends up in the example's <literal>ear/target</literal> directory.
+ All you need to do now is deploy them to GlassFish.
</para>
<para>
You deploy applications to GlassFish using the <ulink src="http://localhost:4848">GlassFish Admin
Console</ulink>. To get the Admin Console running, you need to start a GlassFish domain, in our case
- <literal>domain1</literal>. Switch to the bin folder in the directory where you installed GlassFish and execute
- the following command:
+ <literal>domain1</literal>. Switch to the <literal>bin</literal> folder in the directory where you
+ installed GlassFish and execute the following command:
</para>
<programlisting><![CDATA[$> asadmin start-domain domain1]]></programlisting>
@@ -295,19 +299,18 @@
<title>Deploying to Apache Tomcat</title>
<para>
- Technically, CDI doesn't support servlet containers. That's because the contexts and dependency injection
- services are provided by the Java EE container, not the Servlet API. However, CDI implementations can choose to
- support servlet containers through an extension. Weld does this.</para>
+ Servlet containers are not required to support Java EE services like CDI. However, you can use CDI in a
+ servlet container like Tomcat by embedding a standalone CDI implementation such as Weld.</para>
<para>
- Weld ships with a Servlet listener which bootstraps the CDI environment, registers the BeanManager in JNDI and
- provides injection into servlets. Basically, it emulates the work done by the Java EE container. The only
- limitation is that you cannot use enterprise features such as session beans and container-managed transactions.
+ Weld comes with a servlet listener which bootstraps the CDI environment, registers the <literal>BeanManager</literal>
+ in JNDI and provides injection into servlets. Basically, it emulates some of the work done by the Java EE
+ container. (But you don't get enterprise features such as session beans and container-managed transactions.)
</para>
<para>
- Let's give the Weld servlet extension a spin on Apache Tomcat. First, you'll need to download Tomcat 6.0.18 or later
- from <ulink src="http://tomcat.apache.org/download-60.cgi">tomcat.apache.org</ulink> and extract it.
+ Let's give the Weld servlet extension a spin on Apache Tomcat. First, you'll need to download Tomcat 6.0.18 or
+ later from <ulink src="http://tomcat.apache.org/download-60.cgi">tomcat.apache.org</ulink> and extract it.
</para>
<programlisting><![CDATA[$> unzip apache-tomcat-6.0.18.zip]]></programlisting>
@@ -324,9 +327,9 @@
<para>
In order for Ant to push the artifact to the Tomcat hot deploy directory, it needs to know where the Tomcat
- installation is located. Again, we need to setup a property in the local.build.properties file in the
- examples directory of the Weld distribution. If you haven't yet created this file, do so now. Then assign
- the path of your Tomcat installation to the property key tomcat.home.
+ installation is located. Again, we need to set a property in the <literal>local.build.properties</literal>
+ file in the examples directory of the Weld distribution. If you haven't yet created this file, do so now.
+ Then assign the path of your Tomcat installation to the property key <literal>tomcat.home</literal>.
</para>
<programlisting><![CDATA[tomcat.home=/path/to/apache-tomcat-6]]></programlisting>
@@ -336,7 +339,8 @@
</para>
<para>
- Change to the examples/jsf/numberguess directory again and run the Ant deploy target for Tomcat:
+ Change to the <literal>examples/jsf/numberguess</literal> directory again and run the Ant <literal>deploy</literal>
+ target for Tomcat:
</para>
<programlisting><![CDATA[$> cd examples/jsf/numberguess
@@ -402,20 +406,20 @@
<para>
You can also deploy the application to Tomcat using Maven. This section is a bit more advanced, so skip it
- unless you are itching to use Maven natively. Of course, you'll first need to make sure that you have Maven
+ unless you're itching to use Maven natively. Of course, you'll first need to make sure that you have Maven
installed on your path, similar to how you setup Ant.
</para>
<para>
The Maven plugin communicates with Tomcat over HTTP, so it doesn't care where you have installed Tomcat.
However, the plugin configuration assumes you are running Tomcat in its default configuration, with a hostname
- of localhost and port 8080. The readme.txt file in the example directory has information about how to modify
- the Maven settings to accommodate a different setup.
+ of localhost and port <literal>8080</literal>. The <literal>readme.txt</literal> file in the example directory
+ has information about how to modify the Maven settings to accommodate a different setup.
</para>
<para>
- To allow Maven to communicate with Tomcat over HTTP, edit the conf/tomcat-users.xml file in your Tomcat
- installation and add the following line:
+ To allow Maven to communicate with Tomcat over HTTP, edit the <literal>conf/tomcat-users.xml</literal> file in
+ your Tomcat installation and add the following line:
</para>
<programlisting role="XML"><![CDATA[<user username="admin" password="" roles="manager"/>]]></programlisting>
@@ -433,8 +437,8 @@
<programlisting><![CDATA[$> mvn tomcat:redeploy -Ptomcat]]></programlisting>
<para>
- The <literal>-Ptomcat</literal> argument activates the tomcat profile defined in the Maven POM (pom.xml).
- Among other things, this profile activates the Tomcat plugin.
+ The <literal>-Ptomcat</literal> argument activates the <literal>tomcat</literal> profile defined in the Maven POM
+ (<literal>pom.xml</literal>). Among other things, this profile activates the Tomcat plugin.
</para>
<para>
@@ -445,7 +449,7 @@
<programlisting><![CDATA[$> mvn war:inplace tomcat:run -Ptomcat]]></programlisting>
<para>
- The advantage of using the embedded server is that changes to assets in src/main/webapp take effect
+ The advantage of using the embedded server is that changes to assets in <literal>src/main/webapp</literal> take effect
immediately. If a change to a webapp configuration file is made, the application may automatically redeploy
(depending on the plugin configuration). If you make a change to a classpath resource, you need to execute a
build:
@@ -455,7 +459,7 @@
<para>
There are several other Maven goals that you can use if you are hacking on the example, which are documented in
- the example's readme.txt file.
+ the example's <literal>readme.txt</literal> file.
</para>
</section>
@@ -471,26 +475,28 @@
Support for Jetty in the examples is a more recent addition. Since Jetty is traditionally used with Maven,
there are no Ant targets. You must invoke the Maven build directly to deploy the examples to Jetty out of the
box. Also, only the <literal>weld-numberguess</literal> example is configured for Jetty support at the time of
- this writing.
+ writing.
</para>
<para>
If you've read through the entire Tomcat section, then you're all ready to go. The Maven build parallels the
- embedded Tomcat deployment. If not, don't worry. We'll still go over everything in this section that you need
- to know.
+ embedded Tomcat deployment. If not, don't worry. We'll still go over everything that you need to know again
+ in this section.
</para>
<para>
- The Maven POM (pom.xml) includes a profile named jetty that activates the Maven Jetty plugin, which you can use
+ The Maven POM (<literal>pom.xml</literal>) includes a profile named <literal>jetty</literal> that activates the
+ Maven Jetty plugin, which you can use
to start Jetty in embedded mode and deploy the application in place. You don't need anything else installed
- except to have the Maven command (mvn) on your path. The rest will be downloaded from the internet when the
+ except to have the Maven command (<literal>mvn</literal>) on your path. The rest will be downloaded from the
+ internet when the
build is run.
</para>
<para>
To run the <literal>weld-numberguess</literal> example on Jetty, switch to the example directory and execute
- the inplace goal of the Maven WAR plugin followed by the run goal of the Maven Jetty plugin with the jetty
- profile enabled, as follows:
+ the <literal>inplace</literal> goal of the Maven WAR plugin followed by the <literal>run</literal> goal of
+ the Maven Jetty plugin with the <literal>jetty</literal> profile enabled, as follows:
</para>
<programlisting><![CDATA[$> cd examples/jsf/numberguess
@@ -500,22 +506,23 @@
The log output of Jetty will be shown in the console. Once Jetty reports that the application has deployed, you
can access it at the following local URL: <ulink
src="http://localhost:9090/weld-numberguess">http://localhost:9090/weld-numberguess</ulink>. The port is
- defined in the Maven Jetty plugin configuration within the jetty profile.
+ defined in the Maven Jetty plugin configuration within the <literal>jetty</literal> profile.
</para>
<para>
- Any changes to assets in src/main/webapp take effect immediately. If a change to a webapp configuration file is
- made, the application may automatically redeploy. The redeploy behavior can be fine-tuned in the plugin
- configuration. If you make a change to a classpath resource, you need to execute a build and the inplace goal
- of the Maven WAR plugin, again with the jetty profile enabled.
+ Any changes to assets in <literal>src/main/webapp</literal> take effect immediately. If a change to a webapp
+ configuration file is made, the application may automatically redeploy. The redeploy behavior can be fined-tuned
+ in the plugin configuration. If you make a change to a classpath resource, you need to execute a build and the
+ <literal>inplace</literal> goal of the Maven WAR plugin, again with the <literal>jetty</literal> profile enabled.
</para>
<programlisting><![CDATA[$> mvn compile war:inplace -Pjetty]]></programlisting>
<para>
- The war:inplace goal copies the compiled classes and JARs inside src/main/webapp, under WEB-INF/classes and
- WEB-INF/lib, respectively, mixing source and compiled files. However, the build does work around these
- temporary files by excluding them from the packaged WAR and cleaning them during the Maven clean phase.
+ The <literal>war:inplace</literal> goal copies the compiled classes and JARs inside <literal>src/main/webapp</literal>,
+ under <literal>WEB-INF/classes</literal> and <literal>WEB-INF/lib</literal>, respectively, mixing source and compiled
+ files. However, the build does work around these temporary files by excluding them from the packaged WAR and cleaning
+ them during the Maven clean phase.
</para>
<para>
@@ -531,15 +538,15 @@
<programlisting><![CDATA[$> mvn clean eclipse:clean eclipse:eclipse -Pjetty-ide]]></programlisting>
<para>
- Next, assemble all the necessary resources under src/main/webapp:
+ Next, assemble all the necessary resources under <literal>src/main/webapp</literal>:
</para>
<programlisting><![CDATA[$> mvn war:inplace -Pjetty-ide]]></programlisting>
<para>
Now, you are ready to run the server in Eclipse. Import the project into your Eclipse workspace using "Import
- Existing Project into Workspace. Then, find the start class in src/jetty/java and run its main method as a Java
- Application. Jetty will launch. You can view the application at the following local URL: <ulink
+ Existing Project into Workspace. Then, find the start class in <literal>src/jetty/java</literal> and run its
+ main method as a Java Application. Jetty will launch. You can view the application at the following local URL: <ulink
src="http://localhost:8080">http://localhost:8080</ulink>. Pay particular attention to the port in the URL and
the lack of a trailing context path.
</para>
@@ -557,8 +564,8 @@
<title>The numberguess example in depth</title>
<para>
- In the numberguess application you get given 10 attempts to guess a number between 1 and 100. After each
- attempt, you will be told whether you are too high or too low.
+ In the numberguess application you get 10 attempts to guess a number between 1 and 100. After each
+ attempt, you're told whether your guess was too high or too low.
</para>
<para>
@@ -657,13 +664,13 @@
<note>
<para>
- This demo uses JSF 2 as the view framework, but you can use Weld with any Servlet-based web framework, such
+ This demo uses JSF 2 as the view framework, but you can use Weld with any servlet-based web framework, such
as JSF 1.2 or Wicket.
</para>
</note>
<para>
- Let's take a look at the main JSF view, src/main/webapp/home.xhtml.
+ Let's take a look at the main JSF view, <literal>src/main/webapp/home.xhtml</literal>.
</para>
<programlistingco>
@@ -1167,9 +1174,8 @@
</para>
<para>
Wicket components allow injection, but they <emphasis>cannot</emphasis> use interceptors,
- decorators and lifecycle callbacks such as <literal>@PostConstruct</literal> or
- <literal>@Initializer</literal> methods. The components would need to delegate to actual beans
- to leverage these features.
+ decorators or lifecycle callbacks such as <literal>@PostConstruct</literal> or methods. The
+ components would need to delegate to actual beans to leverage these features.
</para>
</note>
</listitem>
@@ -1182,8 +1188,8 @@
<listitem>
<para>
- In order to activate Wicket for this webapp, the Wicket filter is added to web.xml, and our
- application class is specified in web.xml:
+ In order to activate Wicket for this webapp, the Wicket filter is added to <literal>web.xml</literal>,
+ and our application class is specified in <literal>web.xml</literal>:
</para>
<programlisting role="XML"><![CDATA[<filter>
@@ -1204,8 +1210,8 @@
The servlet listener is still required, as in the Tomcat example, to bootstrap CDI when Jetty
starts and to hook CDI into the Jetty servlet request and session lifecycles. However, rather than
putting it into the web.xml, it is placed into an override file,
- src/main/webapp/WEB-INF/jetty-additions-to-web.xml, that is passed to Jetty as extra descriptor to
- be appended to the web.xml configuration.
+ <literal>src/main/webapp/WEB-INF/jetty-additions-to-web.xml</literal>, that is passed to Jetty as
+ an extra descriptor to be appended to the <literal>web.xml</literal> configuration.
</para>
<programlisting role="XML"><![CDATA[<web-app version="2.4" ...>
Modified: doc/trunk/reference/en-US/injection.xml
===================================================================
--- doc/trunk/reference/en-US/injection.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/injection.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -11,7 +11,7 @@
</para>
<section>
- <title>Where you can @Inject</title>
+ <title>Where you can <literal>@Inject</literal></title>
<para>
Injections are declared using the JSR-330 annotation, <literal>@Inject</literal>, along with an optional set of
@@ -114,7 +114,7 @@
</tip>
<para>
- Bean constructors, initializer methods and injected fields must be annotated <emphasis>@Inject</emphasis>. The
+ Bean constructors, initializer methods and injected fields must be annotated <literal>@Inject</literal>. The
parameters of bean constructors and initializers are injection points, which means the container will search out
beans matching the bean type and qualifier and pass them in as arguments.
</para>
@@ -136,7 +136,7 @@
<para>
This is one of the cases where the <literal>@Inject</literal> annotation <emphasis>is not</emphasis> required at
an injection point. Other cases include observer methods (which we'll meet in <xref linkend="events"/>) and
- disposal methods, which also support parameter injection.
+ disposer methods, which also support parameter injection.
</para>
</section>
@@ -144,7 +144,7 @@
<title>What gets injected</title>
<para>
- The CDI specification defines a procedure, called the <emphasis>typesafe resolution algorithm</emphasis>, that
+ The CDI specification defines a procedure, called <emphasis>typesafe resolution</emphasis>, that
the container follows when identifying the bean to inject to an injection point. This algorithm looks complex
at first, but once you understand it, it's really quite intuitive. Typesafe resolution is performed at system
initialization time, which means that the container will inform the developer immediately if a bean's
@@ -168,6 +168,11 @@
without changes to the client, by enabling or disabling an <emphasis>alternative</emphasis>, or
</para>
</listitem>
+ <listitem>
+ <para>
+ be deployed in different, isolated modules.
+ </para>
+ </listitem>
</itemizedlist>
<para>
@@ -178,8 +183,7 @@
<para>
But then, things start to get complicated. Let's explore how the container determines which bean to inject in
- those not-so-obvious cases by taking a look at qualifiers and how they help your beans fit into the right
- picture.
+ those more advanced cases. We'll start by taking a closer look at qualifiers.
</para>
</section>
@@ -246,7 +250,7 @@
<para>
Qualifier annotations can also qualify method arguments of producer, disposer and observer methods. Combining
- qualified arguments with producer methods is a good way to have an implementation of a bean type at runtime
+ qualified arguments with producer methods is a good way to have an implementation of a bean type
selected at runtime based on the state of the system:
</para>
@@ -276,7 +280,7 @@
<para>
Annotations can have members (i.e., fields) just like regular classes. You can use these fields to further
- discriminate the qualifier. This simply prevents an explosion of annotations that you have to introduce.
+ discriminate the qualifier. This prevents a potential explosion of new annotations.
For instance, if you wanted to create several qualifiers representing different payment methods, you could
aggregate them under a single annotation using a member:
</para>
@@ -289,13 +293,13 @@
}]]></programlisting>
<para>
- Then you select one of the possible values when you use the qualifier:
+ Then you select one of the possible values when you apply the qualifier:
</para>
<programlisting role="JAVA"><![CDATA[private @Inject @PayBy(CHECK) CheckPayment checkPayment;]]></programlisting>
<para>
- You can tell the container to ignore a member of a qualifier type by annotating the member @NonBinding.
+ You can tell the container to ignore a member of a qualifier type by annotating the member <literal>@NonBinding</literal>.
</para>
<programlisting role="JAVA"><![CDATA[@Qualifier
@@ -303,7 +307,7 @@
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface PayBy {
PaymentMethod value();
- @NonBinding String comment;
+ @NonBinding String comment() default "";
}]]></programlisting>
</section>
@@ -312,7 +316,7 @@
<title>Combining qualifiers</title>
<para>
- Both a bean and an injection point may specify multiple qualifiers:
+ Both beans and injection points may specify multiple qualifiers:
</para>
<programlisting role="JAVA"><![CDATA[@Synchronous @Reliable
Modified: doc/trunk/reference/en-US/intro.xml
===================================================================
--- doc/trunk/reference/en-US/intro.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/intro.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -360,7 +360,8 @@
<para>
Bean types may be restricted to an explicit set by annotating the bean with the <literal>@Typed</literal>
annotation and listing the bean types in the value of the annotation. For instance, this bean has been
- restricted to a single bean type, <literal>Shop<Book></literal>:
+ restricted to the bean type explicitly listed, <literal>Shop<Book></literal>, together with
+ <literal>java.lang.Object</literal>:
</para>
<programlisting role="JAVA"><![CDATA[@Typed(Shop.class)
@@ -385,7 +386,7 @@
</para>
<programlisting role="JAVA"><![CDATA[@Qualifier
- at Target( { TYPE, METHOD, PARAMETER, FIELD })
+ at Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface CreditCard {}]]></programlisting>
@@ -412,8 +413,8 @@
<note>
<para>
- If no qualifier is specified at an injection point, the default qualifier, <literal>@Default</literal>, is
- assumed.
+ If an injection point does not explicitly specify a qualifier, it has the default qualifier,
+ <literal>@Default</literal>.
</para>
</note>
@@ -422,7 +423,7 @@
the bean type and all the qualifiers. If it find exactly one matching bean, it injects an instance of
that bean.
</para>
-
+
<para>
We've seen how to indicate that you want to inject a qualified bean. But how do you actually qualify the bean?
By using the annotation, of course! The following bean has the qualifier <literal>@CreditCard</literal>
@@ -436,17 +437,37 @@
<note>
<para>
- If a bean does not explicitly specify a qualifier, it has exactly one qualifier, the default qualifier,
- <literal>@Default</literal>.
+ If a bean does not explicitly specify a qualifier, it has the default qualifier, <literal>@Default</literal>.
</para>
</note>
-
+
+ <!--
+ <note>
+ <para>
+ All beans have the qualifier, <literal>@Any</literal>.
+ </para>
+ </note>
+ -->
+
<para>
CDI defines a simple <emphasis>resolution rule</emphasis> that helps the container decide what to do if there
is more than one bean that satisfies a particular contract. We'll get into the details in
<xref linkend="alternatives"/>.
</para>
-
+
+ <!--
+ <tip>
+ <para>
+ If you're expectng more than one bean to satisfy the contract, you can inject an <literal>Instance</literal>,
+ object which let's you iterate over all the beans which satisfy the contract. For example, we can iterate
+ over all our implementations of <literal>PaymentProcessor</literal> using:
+ </para>
+ <programlisting>@Inject void init(@Any Instance<PaymentProcessor> paymentProcessorInstance) {
+ for (PaymentProcessor pp: paymentProcessorInstance) { ... }
+}</programlisting>
+ </tip>
+ -->
+
</section>
<section>
@@ -538,11 +559,11 @@
<title>Alternatives</title>
<para>
- We've already seen how qualifiers let us choose between multiple implementations of an interface at
- development time. But sometimes we have an interface whose implementation varies depending upon
- the deployment environment. For example, we may want to use a mock implementation in a testing
- environment. An <emphasis>alternative</emphasis> may be declared by annotating the bean class or
- producer method or field with the <literal>@Alternative</literal> annotation.
+ We've already seen how qualifiers let us choose between multiple implementations of an interface
+ at development time. But sometimes we have an interface (or other bean type) whose implementation
+ varies depending upon the deployment environment. For example, we may want to use a mock
+ implementation in a testing environment. An <emphasis>alternative</emphasis> may be declared by
+ annotating the bean class with the <literal>@Alternative</literal> annotation.
</para>
<programlisting role="JAVA"><![CDATA[@Alternative
@@ -550,10 +571,10 @@
<para>
We normally annotate a bean <literal>@Alternative</literal> only when there is some other
- implementation of some interface it implements. We can choose between alternatives at deployment time
- by <emphasis>selecting</emphasis> an alternative using the CDI deployment descriptor
- <literal>META-INF/beans.xml</literal> of the jar or Java EE module that uses it. Different modules
- can specify that they use different alternatives.
+ implementation of an interface it implements (or of any of its bean types). We can choose between
+ alternatives at deployment time by <emphasis>selecting</emphasis> an alternative in the CDI
+ deployment descriptor <literal>META-INF/beans.xml</literal> of the jar or Java EE module that uses
+ it. Different modules can specify that they use different alternatives.
</para>
<para>
@@ -567,51 +588,61 @@
<title>Interceptor binding types</title>
<para>
- Since the introduction of the managed bean specification in Java EE 6, interceptors are available on
- JavaBeans in addition to EJB session beans. That's right, you no longer have to create an EJB just to
- intercept method calls. Holler. So what does CDI have to offer? Well, a lot actually. Let's cover some
- background.
+ You might be familiar with the use of interceptors in EJB 3.0. In Java EE 6, this functionality has
+ been generalized to work with other managed beans. That's right, you no longer have to make your bean
+ an EJB just to intercept its methods. Holler. So what does CDI have to offer above and beyond that? Well,
+ quite a lot actually. Let's cover some background.
</para>
<para>
- The way that interceptors are defined in Java EE 5 is counter-intuitive. You are required to specify the
+ The way that interceptors were defined in Java EE 5 was counter-intuitive. You were required to specify the
<emphasis>implementation</emphasis> of the interceptor directly on the <emphasis>implementation</emphasis>
of the EJB, either in the <literal>@Interceptors</literal> annotation or in the XML descriptor. You might as
- well just put the interceptor code <emphasis>in</emphasis> the implementation. Second, the order in which
+ well just put the interceptor code <emphasis>in</emphasis> the implementation! Second, the order in which
the interceptors are applied is taken from the order in which they are declared in the annotation or the XML
descriptor. Perhaps this isn't so bad if you're applying the interceptors to a single bean. But, if you are
- applying them repeatedly, then there is a chance that you'll inadvertently define a different order for different
- beans. Now that is a problem.
+ applying them repeatedly, then there's a good chance that you'll inadvertently define a different order for
+ different beans. Now that's a problem.
</para>
<para>
- CDI provides a new approach to binding interceptors to beans that introduces a level of abstraction (and
- thus control). You define a special kind of annotation called an <emphasis>interceptor binding
- type</emphasis> whose name describes the role of the interceptor, in this case to add transaction support:
+ CDI provides a new approach to binding interceptors to beans that introduces a level of indirection (and
+ thus control). We define a special kind of annotation called an <emphasis>interceptor binding
+ type</emphasis> whose name describes the behavior implemented by the interceptor, in this case to perform
+ transaction management:
</para>
<programlisting role="JAVA"><![CDATA[@InterceptorBinding
@Inherited
@Target( { TYPE, METHOD })
@Retention(RUNTIME)
-public @interface Transactional {}]]></programlisting>
+public @interface Transactional {}]]></programlisting>
+
+ <para>
+ The interceptor that implements transaction management declares this annotation:
+ </para>
+ <programlisting role="JAVA"><![CDATA[@Transactional @Interceptor
+public class TransactionInterceptor { ... }]]></programlisting>
+
<para>
- Then you apply the annotation to the class whose methods you wish to have intercepted.
+ We you can apply the interceptor to a bean by annotating to the bean class with the same interceptor
+ binding type:
</para>
<programlisting role="JAVA"><![CDATA[@SessionScoped @Transactional
public class ShoppingCart { ... }]]></programlisting>
<para>
- Where is the interceptor? You match the interceptor(s) to apply to the bean by also annotating the
- interceptor class. Never do the two implementations (bean and interceptor) come in direct contact.
- Activating and ordering of the interceptors is then controlled by the XML descriptor, one of the few times
- XML is warranted.
+ Now there's no direct dependency between the two implementations (bean and interceptor). Activation of
+ interceptors is controlled by the CDI deployment descriptor <literal>META-INF/beans.xml</literal>
+ of the jar or Java EE module, allowing us to control which interceptors apply in which deployment
+ scenarios, along with the order of interceptor invocation when multiple interceptors apply to a
+ bean.
</para>
<para>
- We'll discuss bean interceptors, and their cousins, decorators, in <xref linkend="interceptors"/> and <xref
+ We'll discuss interceptors, and their cousins, decorators, in <xref linkend="interceptors"/> and <xref
linkend="decorators"/>.
</para>
@@ -623,20 +654,22 @@
<title>What kinds of classes are beans?</title>
<para>
- We've already seen that JavaBeans and EJBs can be (CDI) beans. Is that the whole story? Let's start from what
- we know, and go from there.
+ We've already seen that JavaBeans and EJB session beans can be (CDI) beans. Is that the whole story? Let's
+ start from what we know, and go from there.
</para>
<section>
<title>Managed beans</title>
<para>
- A managed bean is a bean that is implemented by almost any Java class. This class is called the bean class
- of the managed bean. The basic lifecycle and semantics of a managed bean is defined by the Managed Beans
- specification. If the class is not picked up as a managed bean by the container, then CDI will allow it
- to be a bean if:
+ A managed bean is a Java class. The basic lifecycle and semantics of a managed bean are defined by the
+ Managed Beans specification. You can explicitly declare a managed bean by annotating the bean class
+ <literal>@ManagedBean</literal>, but in CDI you don't need to. According to the specification the CDI
+ container treats any class that satisfies the following conditions as a managed bean:
</para>
+ <blockquote>
+
<itemizedlist>
<listitem>
<para>It is not a non-static inner class.</para>
@@ -646,11 +679,14 @@
</listitem>
<listitem>
<para>
- It is neither annotated with an EJB component-defining annotation or declared as an EJB bean class in
- ejb-jar.xml.
+ It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in
+ <literal>ejb-jar.xml</literal>.
</para>
</listitem>
<listitem>
+ <para>It does not implement <literal>javax.enterprise.inject.spi.Extension</literal>.</para>
+ </listitem>
+ <listitem>
<para>
It has an appropriate constructor—either:
</para>
@@ -664,16 +700,18 @@
</itemizedlist>
</listitem>
</itemizedlist>
+
+ </blockquote>
+
+ <para>The unrestricted set of bean types for a managed bean contains the bean class, every superclass and all
+ interfaces it implements directly or indirectly.</para>
- <para>
- <emphasis>Unlike</emphasis> the managed bean definition, no special declaration is required to define a
- managed bean. CDI takes advantage of the fact that the Managed Bean specification allows companion
- specifications to relax the requirement of having to add the <literal>@ManagedBean</literal> annotation.
- </para>
+ <para>If a managed bean has a public field, it must have the default scope <literal>@Dependent</literal>.</para>
<para>
- Some managed beans are much more. Those are the session beans. While still technically managed beans, they
- have enough additional, enterprise features, that we consider them to be their own kind.
+ Session beans are also, technically, managed beans. However, since they have their own special lifecycle and
+ take advantage of additional enterprise services, the CDI specification considers them to be a different
+ kind of bean.
</para>
</section>
@@ -682,19 +720,20 @@
<title>Session beans</title>
<para>
- EJB 3 session beans belong to the EJB specification. That is, the basic lifecycle and semantics. Beyond
- that, they get to participate in CDI just like any other bean. There are some restrictions about which
- scopes can be assigned to a session bean, but other than that, they are interchangeable with regular managed
- beans. That means you can inject one session bean into another, a managed bean into a session bean, a
- session bean into a managed bean, have a managed bean observe an event raised by a session bean, and so on.
+ Session beans belong to the EJB specification. They have a special lifecycle, state management and concurrency
+ model that is different to other managed beans and non-managed Java objects. But session beans participate in
+ CDI just like any other bean. There are some restrictions upon the scope that can be assigned to a session bean,
+ but apart from than that, they may be used interchangeably with regular managed beans. That means you can inject
+ one session bean into another session bean, a managed bean into a session bean, a session bean into a managed
+ bean, have a managed bean observe an event raised by a session bean, and so on.
</para>
<note>
<para>
Message-driven and entity beans are by nature non-contextual objects and may not be injected into other
- objects. Message-driven beans can take advantage of some CDI functionality, such as dependency injection
- and interceptors. In fact, CDI will perform injection into any message-driven or session bean, even those
- which are not contextual instances.
+ objects. However, message-driven beans can take advantage of some CDI functionality, such as dependency
+ injection, interceptors and decorators. In fact, CDI will perform injection into any session or
+ message-driven bean, even those which are not contextual instances.
</para>
</note>
@@ -706,15 +745,20 @@
types.
</para>
+ <para>There's no reason to explicitly declare the scope of a stateless session bean or singleton session bean.
+ The EJB container controls the lifecycle of these beans, according to the semantics of the <literal>@Stateless</literal>
+ or <literal>@Singleton</literal> declaration. On the other hand, a stateful session bean may have any scope.</para>
+
<para>
- Stateful session beans can define a no arguments remove method, annotated <literal>@Remove</literal>, that
- is used by the application to indicate the instance should be destroyed. However, in a CDI environment, this
- method can only be executed by the application if the bean is dependent-scoped. Otherwise, it's illegal for
- the application to invoke this method because the container is controlling its lifecycle.
+ Stateful session beans may define a <emphasis>remove method</emphasis>, annotated <literal>@Remove</literal>,
+ that is used by the application to indicate that an instance should be destroyed. However, for a contextual
+ instance of the bean—an instance under the control of CDI—this method may only be called by the
+ application if the bean has scope <literal>@Dependent</literal>. For beans with other scopes, the application
+ must let the container destroy the bean.
</para>
<para>
- So, when should we use a session instead of a basic managed bean? Whenever we need the advanced enterprise
+ So, when should we use a session bean instead of a plain managed bean? Whenever we need the advanced enterprise
services offered by EJB, such as:
</para>
@@ -730,19 +774,19 @@
instance-pooling for stateless session beans,</para>
</listitem>
<listitem>
- <para>remote and web service invocation, and</para>
+ <para>remote or web service invocation, or</para>
</listitem>
<listitem>
<para>timers and asynchronous methods,</para>
</listitem>
</itemizedlist>
- <para>When we don't need any of these things, a basic managed bean will serve just fine.</para>
+ <para>When we don't need any of these things, an ordinary managed bean will serve just fine.</para>
<para>
- Many beans (including any session or application scoped bean) are available for concurrent access.
- Therefore, the concurrency management provided by EJB 3.1 is especially useful. Most session and application
- scoped beans should be EJBs.
+ Many beans (including any <literal>@SessionScoped</literal> or <literal>@ApplicationScoped</literal>
+ beans) are available for concurrent access. Therefore, the concurrency management provided by EJB 3.1
+ is especially useful. Most session and application scoped beans should be EJBs.
</para>
<para>
@@ -758,57 +802,43 @@
</para>
<para>
- The point is, you use a session bean when you need the services it provides, not just because you want to
- use dependency injection, lifecycle management, or interceptors. The Java EE programming model makes a
- whole lot more sense now; you won't need to go off and invent your own bean container to make programming
- in Java EE palatable.
+ The point we're trying to make is: use a session bean when you need the services it provides, not just
+ because you want to use dependency injection, lifecycle management, or interceptors. Java EE 6 provides
+ a graduated programming model. It's usually easy to start with an ordinary managed bean, and later turn
+ it into an EJB just by adding one of the following annotations: <literal>@Stateless</literal>,
+ <literal>@Stateful</literal> or <literal>@Singleton</literal>.
</para>
-
+
<para>
- In fact, it's easy to start with simple managed bean, and later turn it into an EJB just by adding one of
- the following annotations: <literal>@Stateless</literal>, <literal>@Stateful</literal> or
- <literal>@Singleton</literal>.
+ On the other hand, don't be scared to use session beans just because you've heard your friends say that
+ they're "heavyweight". It's nothing more than supersitition to think that something is "heavier" just
+ because it's hosted natively within the Java EE container, instead of by a proprietary bean container
+ or dependency injection framework that runs as an additional layer of obfuscation. And as a general
+ principle, you should be skeptical of folks who use vaguely defined terminology like "heavyweight".
</para>
-
+
</section>
<section>
<title>Producer methods</title>
<para>
- Surely not everything you want to inject can be a bean class. What if you need to inject the implementation
- of an API that varies at runtime? And how would you inject objects that are created by another mechanism,
- such as a JPA result? Fortunately, the CDI specification recognized these and other cases and introduced the
- concept of a producer method.
+ Not everything that needs to be injected can be boiled down to a bean class instantiated by the container
+ using <literal>new</literal>. There are plenty of cases where we need additional control. What if we need
+ to decide at runtime which implementation of a type to instantiate and inject? What if we need to inject an
+ object that is obtained by querying a service or transaction resource, for example by executing a JPA query?
</para>
<para>
- A <emphasis>producer method</emphasis> is a method on a bean that is used as a bean source, meaning the
- method itself describes the bean and the container invokes the method to obtain an instance of the bean when
- no instance exists in its specified context. A producer method lets the application take full control of the
- instantiation process, specifically when:
+ A <emphasis>producer method</emphasis> is a method that acts as a source of bean instances, meaning the
+ method declaration itself describes the bean and the container invokes the method to obtain an instance of
+ the bean when no instance exists in the specified context. A producer method lets the application take full
+ control of the instantiation process.
</para>
- <itemizedlist>
- <listitem>
- <para>
- the objects to be injected are not required to be instances of beans, or
- </para>
- </listitem>
- <listitem>
- <para>
- the concrete type of the objects to be injected may vary at runtime, or
- </para>
- </listitem>
- <listitem>
- <para>
- the objects require some custom initialization that is not performed by the bean constructor.
- </para>
- </listitem>
- </itemizedlist>
-
<para>
- For example:
+ A producer method is declared by annotating a method of a bean class with the <literal>@Produces</literal>
+ annotation.
</para>
<programlisting role="JAVA"><![CDATA[@ApplicationScoped
@@ -823,20 +853,21 @@
}]]></programlisting>
<para>
- Obviously, you cannot define a bean that is itself a random number. A producer method allows you do define
- its result as a bean, in this case an <literal>Integer</literal> with qualifier <literal>@Random</literal>,
- scope <literal>@Dependent</literal> (implied) and name <literal>randomNumber</literal> (derived from bean
- property convention; otherwise it would be the same as the method name). It can be injected just like any
- other bean:
+ We can't write a bean class that is itself a random number. But we can certainly write a method that returns
+ a random number. By making the method a producer method, we allow the return value of the method—in this
+ case an <literal>Integer</literal>—to be injected. We can even specify a qualifier—in this case
+ <literal>@Random</literal>, a scope—which in this case defaults to <literal>@Dependent</literal>,
+ and an EL name—which in this case defaults to <literal>randomNumber</literal> according to the JavaBeans
+ property name convention. Now we can get a random number anywhere:
</para>
<programlisting role="JAVA"><![CDATA[@Inject @Random int randomNumber;]]></programlisting>
<para>
- or used in a Unified EL expression:
+ Even in a Unified EL expression:
</para>
- <programlisting><![CDATA[Your raffle number is #{randomNumber}.]]></programlisting>
+ <programlisting><![CDATA[<p>Your raffle number is #{randomNumber}.</p>]]></programlisting>
<para>
A producer method must be a non-abstract method of a managed bean class or session bean class. A producer
@@ -870,72 +901,41 @@
</itemizedlist>
<para>
- Some producer methods return objects that require explicit destruction:
+ If the producer method has method parameters, the container will look for a bean that satisfies the type
+ and qualifiers of each parameter and pass it to the method automatically—another form of
+ dependency injection.
</para>
-
- <programlisting role="JAVA"><![CDATA[@Produces @RequestScoped Connection connect(User user) {
- return createConnection(user.getId(), user.getPassword());
-}]]></programlisting>
-
- <para>
- If the producer method has method arguments, as in this example, the container will look for matching beans
- and pass them into the method automatically—another form of dependency injection.
- </para>
- <para>Producer methods may also define matching <emphasis>disposal methods</emphasis>:</para>
-
- <programlisting role="JAVA"><![CDATA[void close(@Disposes Connection connection) {
- connection.close();
+ <programlisting role="JAVA"><![CDATA[@Produces Set<Roles> getRoles(User user) {
+ return user.getRoles();
}]]></programlisting>
- <para>
- The disposal method is called automatically when the context ends (in this case, the end of the request).
- The disposal method requires at least one parameter, the bean produced by the producer method. Any
- additional parameters will be satisfied by the container.
- </para>
+ <para>We'll talk much more about producer methods in <xref linkend="producermethods"/>.</para>
- <para>We'll talk much more about producer and disposal methods in <xref linkend="producermethods"/>.</para>
-
</section>
<section>
<title>Producer fields</title>
<para>
- A <emphasis>producer field</emphasis> is a simpler alternative to a producer method and can also marry
- dependency injection with bean definition. A producer field may be declared by annotating a field of a
- managed bean class or session bean class with the <literal>@Produces</literal> annotation previously used on
- producer methods.
+ A <emphasis>producer field</emphasis> is a simpler alternative to a producer method. A producer field is
+ declared by annotating a field of a bean class with the <literal>@Produces</literal> annotation—the
+ same annotation used for producer methods.
</para>
<programlisting role="JAVA"><![CDATA[public class Shop {
@Produces PaymentProcessor paymentProcessor = ....;
- @Produces List<Product> products = ....;
-}]]></programlisting>
-
- <para>
- A producer field may also specify scope, name, stereotypes and/or qualifiers. It's a good way to expose
- state from a bean as a top-level bean.
- </para>
-
- <programlisting role="JAVA"><![CDATA[public class Shop {
- @Produces @Wishlist @Named("wishlist") List<Product> products = ....;
-}]]></programlisting>
-
- <para>
- The result can be injected or used in a Unified EL expression.
- </para>
+ @Produces @Catalog List<Product> products = ....;
+}]]></programlisting>
- <programlisting role="JAVA"><![CDATA[@Inject @Wishlist List<Product> wishlist;]]></programlisting>
- <programlisting role="XML"><![CDATA[<h:dataTable var="_product" value="#{wishlist}">...</h:dataTable>]]></programlisting>
-
<para>
- The rules for determining the bean types of a producer field parallel the rules for producer method.
+ The rules for determining the bean types of a producer field parallel the rules for producer methods.
</para>
<para>
- Aside from convenience, producer fields serve a specific purpose as an adapter for Java EE resources
- injections.
+ A producer field is really just a shortcut that lets us avoid writing a useless getter method. However,
+ in addition to convenience, producer fields serve a specific purpose as an adaptor for Java EE component
+ environment injection.
</para>
</section>
@@ -944,48 +944,73 @@
<title>Java EE resources</title>
<para>
- Java EE 5 already introduced some support for dependency injection, in the form of resource injections. A
- resources is either a component defined in JNDI such as a data source or a container-provided component such
- as a persistence unit, persistence context, EJB or web service.
+ Java EE 5 already introduced some limited support for dependency injection, in the form of component
+ environment injection. A component environment resource is a Java EE component, for example a JDBC
+ datasource, JMS queue or topic, JPA persistence context, remote EJB or web service.
</para>
<para>
- Naturally, there remained some mismatch with the new style of dependency injection in CDI. Most notably,
- resource injections rely on string-based names to qualify ambiguous types, and there is no real consistency
- as to how a resource obtains its name (sometimes JNDI, other times from an XML descriptor or even a default
- name). Producer fields turned out to be an elegant adapter to rein them in and get them to participate in
- the CDI system just like any other injectable bean.
+ Naturally, there is now a slight mismatch with the new style of dependency injection in CDI. Most notably,
+ component environment injection relies on a string-based name to qualify an ambiguous type, and there is no
+ real consistency as to the nature of that name (sometimes a JNDI name, other times from an XML descriptor
+ or even a default name). Producer fields turned out to be an elegant adaptor to reduce all this complexity
+ to a common model and get component environment resources to participate in the CDI system just like any
+ other kind of bean.
</para>
<para>
- Producer fields have a duality in that they can both accept a standard Java EE resource injection and
- produce a bean that can be injected into another bean in a typesafe way. Here are some examples of these
- injection points. Notice that a qualifier annotation can be assigned at the injection point to adapt the
- string-based name required by the injection point into a typesafe qualifier for injection elsewhere.
+ Fields have a duality in that they can both be the target of Java EE component environment injection and be
+ declared as a CDI producer field. Therefore, they can define a mapping from a string-based name in the
+ component environment, to a combination of type and qualifiers used in the world of typesafe injection. We
+ call a producer field that represents a reference to an object in the Java EE component environment a
+ <emphasis>resource</emphasis>.
</para>
- <programlisting role="JAVA"><![CDATA[@Produces @WebServiceRef(lookup="java:app/service/PaymentService")
-PaymentService paymentService;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Produces @WebServiceRef(lookup="java:app/service/Catalog")
+Catalog catalog;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Produces @Resource(lookup="java:global/env/jdbc/CustomerDatasource")
+ at CustomerDatabase Datasource customerDatabase;]]></programlisting>
+
<programlisting role="JAVA"><![CDATA[@Produces @PersistenceContext(unitName="CustomerDatabase")
- at CustomerDatabase EntityManager customerDatabasePersistenceContext;]]></programlisting>
+ at CustomerDatabase EntityManager customerDatabasePersistenceContext;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Produces @PersistenceUnit(unitName="CustomerDatabase")
+ at CustomerDatabase EntityManagerFactory customerDatabasePersistenceUnit;]]></programlisting>
+
+ <programlisting role="JAVA"><![CDATA[@Produces @EJB(ejbLink="../their.jar#PaymentService")
+PaymentService paymentService;]]></programlisting>
+
<para>
These resources can then be injected in the usual way.
</para>
+ <programlisting role="JAVA"><![CDATA[@Inject Catalog catalog;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @CustomerDatabase Datasource customerDatabase;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @CustomerDatabase EntityManager customerDatabaseEntityManager;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @CustomerDatabase EntityManagerFactory customerDatabaseEntityManagerFactory;]]></programlisting>
<programlisting role="JAVA"><![CDATA[@Inject PaymentService paymentService;]]></programlisting>
- <programlisting role="JAVA"><![CDATA[@Inject @CustomerDatabase EntityManager customerDatabaseEntityManager;]]></programlisting>
<para>
The bean type and qualifiers of the resource are determined by the producer field declaration.
</para>
<para>
- While you may have to introduce a couple extra managed beans to serve as typesafe adapters, it's well worth
- the effort so that you can minimize the number of places in your code you have to repeat the old-style
- dependency injection and string-based qualifiers.
+ It might seem like a pain to have to write these extra producer field declarations, just to gain an additional
+ level of indirection. You could just as well use component environment injection directly, right? But remember
+ that you're going to be using resources like the <literal>EntityManager</literal> in several different beans.
+ Isn't it nicer and more typesafe to write
</para>
+
+ <programlisting>@Inject @CustomerDatabase EntityManager</programlisting>
+
+ <para>instead of</para>
+
+ <programlisting>@PersistenceContext(unitName="CustomerDatabase") EntityManager</programlisting>
+
+ <para>
+ all over the place?
+ </para>
</section>
@@ -993,41 +1018,36 @@
<title>Built-in beans</title>
<para>
- Java EE gives you some other goodies in the form of built-in beans. A Java EE (or embeddable EJB) container
- provide the following built-in beans, all of which have qualifier <literal>@Default</literal>:
+ In the Java EE environment, we get some additional goodies. The container provides the following
+ built-in beans, all with the qualifier <literal>@Default</literal>:
</para>
<itemizedlist>
<listitem>
<para>
- a bean with bean type <literal>javax.transaction.UserTransaction</literal>, allowing injection of a
- reference to the JTA <literal>UserTransaction</literal>,
+ the current JTA <literal>UserTransaction</literal>,
</para>
</listitem>
<listitem>
<para>
- a bean with bean type <literal>javax.security.Principal</literal>, allowing injection of a
- <literal>Principal</literal> representing the current caller identity.
+ a <literal>Principal</literal> representing the current caller identity,
</para>
</listitem>
<listitem>
<para>
- a bean with bean type <literal>javax.validation.ValidationFactory</literal>, allowing injection of the
- default <ulink src="http://jcp.org/en/jsr/detail?id=303">Bean Validation</ulink>
+ the default <ulink src="http://jcp.org/en/jsr/detail?id=303">Bean Validation</ulink>
<literal>ValidationFactory</literal>, and
</para>
</listitem>
<listitem>
<para>
- a bean with bean type <literal>javax.validation.Validator</literal>, allowing injection of a Validator
- for the default Bean Validation <literal>ValidationFactory</literal>.
+ a <literal>Validator</literal> for the default <literal>ValidationFactory</literal>.
</para>
</listitem>
</itemizedlist>
<para>
- Aren't you excited to start using this stuff? Wait no longer. In the next two chapters, we'll look at some
- examples.
+ Can't wait to get started? Great! In the next two chapters, we'll start working on some examples.
</para>
</section>
Modified: doc/trunk/reference/en-US/producermethods.xml
===================================================================
--- doc/trunk/reference/en-US/producermethods.xml 2009-11-07 14:00:02 UTC (rev 4728)
+++ doc/trunk/reference/en-US/producermethods.xml 2009-11-07 15:49:22 UTC (rev 4729)
@@ -181,7 +181,36 @@
</para>
</section>
+
+ <section>
+ <title>Disposer methods</title>
+ <para>
+ Some producer methods return objects that require explicit destruction. For example, somebody needs to
+ close this JDBC connection:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Produces @RequestScoped Connection connect(User user) {
+ return createConnection(user.getId(), user.getPassword());
+}]]></programlisting>
+
+ <para>Destruction can be performed by a matching <emphasis>disposer method</emphasis>, defined
+ by the same class as the producer method:</para>
+
+ <programlisting role="JAVA"><![CDATA[void close(@Disposes Connection connection) {
+ connection.close();
+}]]></programlisting>
+
+ <para>
+ The disposer method must have at least one parameter, annotated <literal>@Disposes</literal>, with the same
+ type and qualifiers as the producer method. The disposer method is called automatically when the context ends
+ (in this case, at the end of the request), and this parameter receives the object produced by the producer
+ method. If the disposer method has additional method parameters, the container will look for a bean that
+ satisfies the type and qualifiers of each parameter and pass it to the method automatically.
+ </para>
+
+ </section>
+
<!--
vim:et:ts=3:sw=3:tw=120
-->
More information about the weld-commits
mailing list