Author: gavin.king(a)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...
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...
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[(a)Typed(Shop.class)
@@ -385,7 +386,7 @@
</para>
<programlisting role="JAVA"><![CDATA[@Qualifier
-@Target( { TYPE, METHOD, PARAMETER, FIELD })
+@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>(a)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")
+@CustomerDatabase Datasource customerDatabase;]]></programlisting>
+
<programlisting role="JAVA"><![CDATA[@Produces
@PersistenceContext(unitName="CustomerDatabase")
-@CustomerDatabase EntityManager
customerDatabasePersistenceContext;]]></programlisting>
+@CustomerDatabase EntityManager
customerDatabasePersistenceContext;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Produces
@PersistenceUnit(unitName="CustomerDatabase")
+@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
-->