[weld-commits] Weld SVN: r4536 - doc/trunk/reference/en-US.
weld-commits at lists.jboss.org
weld-commits at lists.jboss.org
Sun Nov 1 21:51:58 EST 2009
Author: dan.j.allen
Date: 2009-11-01 21:51:56 -0500 (Sun, 01 Nov 2009)
New Revision: 4536
Modified:
doc/trunk/reference/en-US/Author_Group.xml
doc/trunk/reference/en-US/Book_Info.xml
doc/trunk/reference/en-US/decorators.xml
doc/trunk/reference/en-US/ee.xml
doc/trunk/reference/en-US/environments.xml
doc/trunk/reference/en-US/events.xml
doc/trunk/reference/en-US/example.xml
doc/trunk/reference/en-US/extend.xml
doc/trunk/reference/en-US/extensions.xml
doc/trunk/reference/en-US/gettingstarted.xml
doc/trunk/reference/en-US/injection.xml
doc/trunk/reference/en-US/interceptors.xml
doc/trunk/reference/en-US/intro.xml
doc/trunk/reference/en-US/master.xml
doc/trunk/reference/en-US/next.xml
doc/trunk/reference/en-US/part1.xml
doc/trunk/reference/en-US/part2.xml
doc/trunk/reference/en-US/part3.xml
doc/trunk/reference/en-US/part4.xml
doc/trunk/reference/en-US/part5.xml
doc/trunk/reference/en-US/producermethods.xml
doc/trunk/reference/en-US/ri-spi.xml
doc/trunk/reference/en-US/scopescontexts.xml
doc/trunk/reference/en-US/specialization.xml
doc/trunk/reference/en-US/stereotypes.xml
doc/trunk/reference/en-US/viewlayers.xml
doc/trunk/reference/en-US/xml.xml
Log:
completed full revision of ref guide to reflect RI and spec name change and spec updates through PFD2
Modified: doc/trunk/reference/en-US/Author_Group.xml
===================================================================
--- doc/trunk/reference/en-US/Author_Group.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/Author_Group.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,41 +1,42 @@
-<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<authorgroup>
- <author>
- <firstname>Gavin</firstname>
- <surname>King</surname>
- <affiliation>
- <jobtitle>JSR-299 specification lead</jobtitle>
- <orgname>Red Hat, Inc.</orgname>
- </affiliation>
- </author>
- <author>
- <firstname>Pete</firstname>
- <surname>Muir</surname>
- <affiliation>
- <jobtitle>Web Beans (JSR-299 Reference Implementation) lead
- </jobtitle>
- <orgname>Red Hat, Inc.</orgname>
- </affiliation>
- </author>
<author>
+ <firstname>Gavin</firstname>
+ <surname>King</surname>
+ <affiliation>
+ <jobtitle>JSR-299 specification lead</jobtitle>
+ <orgname>Red Hat, Inc.</orgname>
+ </affiliation>
+ </author>
+ <author>
+ <firstname>Pete</firstname>
+ <surname>Muir</surname>
+ <affiliation>
+ <jobtitle>Weld (JSR-299 Reference Implementation) lead
+ </jobtitle>
+ <orgname>Red Hat, Inc.</orgname>
+ </affiliation>
+ </author>
+ <author>
<firstname>Dan</firstname>
<surname>Allen</surname>
- <affiliation>
- <jobtitle>Senior Software Engineer</jobtitle>
- <orgname>Red Hat, Inc.</orgname>
- </affiliation>
+ <affiliation>
+ <jobtitle>Senior Software Engineer</jobtitle>
+ <orgname>Red Hat, Inc.</orgname>
+ </affiliation>
</author>
<author>
<firstname>David</firstname>
<surname>Allen</surname>
</author>
- <othercredit>
- <firstname>Nicola</firstname>
- <surname>Benaglia</surname>
- <contrib>Italian Translation</contrib>
- </othercredit>
<othercredit>
+ <firstname>Nicola</firstname>
+ <surname>Benaglia</surname>
+ <contrib>Italian Translation</contrib>
+ </othercredit>
+ <othercredit>
<firstname>Gladys</firstname>
<surname>Guerrero</surname>
<contrib>Spanish Translation</contrib>
@@ -72,4 +73,7 @@
<orgname>Kava Community</orgname>
</affiliation>
</othercredit>
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
</authorgroup>
Modified: doc/trunk/reference/en-US/Book_Info.xml
===================================================================
--- doc/trunk/reference/en-US/Book_Info.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/Book_Info.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -3,9 +3,8 @@
<bookinfo>
<title>Weld - JSR-299 Reference Implementation</title>
<subtitle>
- JSR-299: The new Java standard for dependency injection and contextual life cycle management
+ JSR-299: The new Java standard for dependency injection and contextual lifecycle management
</subtitle>
-
<xi:include href="Author_Group.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<!--
vim:et:ts=3:sw=3:tw=120
Modified: doc/trunk/reference/en-US/decorators.xml
===================================================================
--- doc/trunk/reference/en-US/decorators.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/decorators.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,132 +1,191 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="decorators">
-<chapter id="decorators">
- <title>Decorators</title>
+ <title>Decorators</title>
- <para>Interceptors are a powerful way to capture and separate concerns
- which are <emphasis>orthogonal</emphasis> to the type system. Any
- interceptor is able to intercept invocations of any Java type. This makes
- them perfect for solving technical concerns such as transaction management
- and security. However, by nature, interceptors are unaware of the actual
- semantics of the events they intercept. Thus, interceptors aren't an
- appropriate tool for separating business-related concerns.</para>
+ <para>
+ Interceptors are a powerful way to capture and separate concerns which are <emphasis>orthogonal</emphasis> to the
+ application (and type system). Any interceptor is able to intercept invocations of any Java type. This makes them
+ perfect for solving technical concerns such as transaction management, security and call logging. However, by
+ nature, interceptors are unaware of the actual semantics of the events they intercept. Thus, interceptors aren't
+ an appropriate tool for separating business-related concerns.
+ </para>
- <para>The reverse is true of <emphasis>decorators</emphasis>. A decorator
- intercepts invocations only for a certain Java interface, and is therefore
- aware of all the semantics attached to that interface. This makes decorators
- a perfect tool for modeling some kinds of business concerns. It also
- means that a decorator doesn't have the generality of an interceptor.
- Decorators aren't able to solve technical concerns that cut across many
- disparate types.</para>
+ <para>
+ The reverse is true of <emphasis>decorators</emphasis>. A decorator intercepts invocations only for a certain Java
+ interface, and is therefore aware of all the semantics attached to that interface. Since decorators directly
+ implement operations with business semantics, it makes them the perfect tool for modeling some kinds of business
+ concerns. It also means that a decorator doesn't have the generality of an interceptor. Decorators aren't able to
+ solve technical concerns that cut across many disparate types. The two complement one another. Let's look at some
+ cases where decorators fit the bill.
+ </para>
- <para>Suppose we have an interface that represents accounts:</para>
+ <para>Suppose we have an interface that represents accounts:</para>
-<programlisting role="JAVA"><![CDATA[public interface Account {
- public BigDecimal getBalance();
- public User getOwner();
- public void withdraw(BigDecimal amount);
- public void deposit(BigDecimal amount);
+ <programlisting role="JAVA"><![CDATA[public interface Account {
+ public BigDecimal getBalance();
+ public User getOwner();
+ public void withdraw(BigDecimal amount);
+ public void deposit(BigDecimal amount);
}]]></programlisting>
- <para>Several different Web Beans in our system implement the
- <literal>Account</literal> interface. However, we have a common legal
- requirement that, for any kind of account, large transactions must be
- recorded by the system in a special log. This is a perfect job for a
- decorator.</para>
+ <para>
+ Several different beans in our system implement the <literal>Account</literal> interface. However, we have a
+ common legal requirement that; for any kind of account, large transactions must be recorded by the system in a
+ special log. This is a perfect job for a decorator.
+ </para>
- <para>A decorator is a simple Web Bean that implements the type it
- decorates and is annotated <literal>@Decorator</literal>.</para>
+ <para>
+ A decorator is a bean (possibly even an abstract class) that implements the type it decorates and is annotated
+ <literal>@Decorator</literal>.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Decorator
-public abstract class LargeTransactionDecorator
- implements Account {
+ <programlisting role="JAVA"><![CDATA[@Decorator
+public abstract class LargeTransactionDecorator
+ implements Account {
+ ...
+}]]></programlisting>
- @Decorates Account account;
+ <para>
+ So what goes in the decorator? Well, decorators have to inject the instance of the bean they are decorating,
+ termed the <emphasis>delegate injection point</emphasis>. The injection point has the same type as the bean to
+ decorate and the annotation <literal>@Delegate</literal>. There can be at most one injection point, which can be a
+ constructor, initializer method or field injection.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Decorator
+public abstract class LargeTransactionDecorator
+ implements Account {
+ @Inject @Delegate @Any Account account;
+ ...
+}]]></programlisting>
+
+ <para>
+ You'll see in a moment that the beans which are decorated can be further restricted by specifying qualifiers at
+ the injection point, a familiar pattern in CDI.
+ </para>
+
+ <para>
+ The decorator then implements any methods of the bean type it wants to decorate. The decorator can in turn invoke
+ the method on the decorated instance. Note that the method on the decorate is being called by the container
+ <emphasis>instead of</emphasis> the method on the bean instance. It's up to the decorator to invoke the method on
+ the bean instance. In fact, the decorator can invoke any method on the bean instance.
+ </para>
- @PersistenceContext EntityManager em;
+ <programlisting role="JAVA"><![CDATA[@Decorator
+public abstract class LargeTransactionDecorator
+ implements Account {
+ @Inject @Delegate @Any Account account;
+
+ @PersistenceContext EntityManager em;
- public void withdraw(BigDecimal amount) {
- account.withdraw(amount);
- if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
- em.persist( new LoggedWithdrawl(amount) );
- }
+ public void withdraw(BigDecimal amount) {
+ account.withdraw(amount);
+ if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
+ em.persist( new LoggedWithdrawl(amount) );
+ }
}
- public void deposit(BigDecimal amount);
- account.deposit(amount);
- if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
- em.persist( new LoggedDeposit(amount) );
- }
- }
-
+ public void deposit(BigDecimal amount);
+ account.deposit(amount);
+ if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
+ em.persist( new LoggedDeposit(amount) );
+ }
+ }
}]]></programlisting>
- <para>Unlike other simple Web Beans, a decorator may be an abstract
- class. If there's nothing special the decorator needs to do for a
- particular method of the decorated interface, you don't need to
- implement that method.</para>
+ <para>
+ Interceptors for a method are called before decorators that apply to that method.
+ </para>
+
+ <para>
+ Unlike other beans, a decorator may be an abstract class. Therefore, if there's nothing special the decorator
+ needs to do for a particular method of the decorated interface, you don't need to implement that method.
+ </para>
- <section>
- <title>Delegate attributes</title>
+ <section>
+ <title>Delegate object</title>
- <para>All decorators have a <emphasis>delegate attribute</emphasis>.
- The type and binding types of the delegate attribute determine which
- Web Beans the decorator is bound to. The delegate attribute type must
- implement or extend all interfaces implemented by the decorator.</para>
+ <para>
+ All decorators must have a delegate injection point that injects the delegate object, as shown above. The type
+ and qualifier types of the delegate injection point determine which beans the decorator is bound to. The
+ delegate object type must implement or extend all interfaces implemented by the decorator.
+ </para>
- <para>This delegate attribute specifies that the decorator is bound to
- all Web Beans that implement <literal>Account</literal>:</para>
+ <para>
+ This delegate injection point specifies that the decorator is bound to all beans that implement
+ <literal>Account</literal>:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Decorates Account account;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Delegate @Any Account account;]]></programlisting>
- <para>A delegate attribute may specify a binding annotation. Then the
- decorator will only be bound to Web Beans with the same binding.</para>
+ <para>
+ A delegate injection point may specify any number of qualifier annotations. Then the decorator will only be
+ bound to beans with the same qualifiers.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Decorates @Foreign Account account;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Delegate @Foreign Account account;]]></programlisting>
- <para>A decorator is bound to any Web Bean which:</para>
+ <para>A decorator is bound to any bean which:</para>
- <itemizedlist>
- <listitem>
- <para>has the type of the delegate attribute as an API type, and</para>
- </listitem>
- <listitem>
- <para>has all binding types that are declared by the delegate attribute.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>has the type of the delegate object as a bean type, and</para>
+ </listitem>
+ <listitem>
+ <para>has all qualifiers that are declared at the delegate injection point.</para>
+ </listitem>
+ </itemizedlist>
- <para>The decorator may invoke the delegate attribute, which has much the same
- effect as calling <literal>InvocationContext.proceed()</literal> from an
- interceptor.</para>
+ <para>
+ The decorator may invoke the delegate object, which has much the same effect as calling
+ <literal>InvocationContext.proceed()</literal> from an interceptor. The main difference is that the decorator
+ can invoke <emphasis>any</emphasis> business method on the delegate object.
+ </para>
- </section>
+ </section>
-<section>
- <title>Enabling decorators</title>
+ <section>
+ <title>Enabling decorators</title>
- <para>We need to <emphasis>enable</emphasis> our decorator in
- <literal>web-beans.xml</literal>.</para>
+ <para>
+ By default, all decorators are disabled. We need to <emphasis>enable</emphasis> our decorator in the
+ <literal>beans.xml</literal> descriptor of a bean deployment archive. This activation only applies
+ to beans in the same archive.
+ </para>
-<programlisting role="XML"><![CDATA[<Decorators>
- <myapp:LargeTransactionDecorator/>
-</Decorators>]]></programlisting>
+ <programlisting role="XML"><![CDATA[<beans
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+ <decorators>
+ <class>org.mycompany.myapp.LargeTransactionDecorator</class>
+ </decorators>
+</beans>]]></programlisting>
- <para>This declaration serves the same purpose for decorators that the
- <literal><Interceptors></literal> declaration serves for interceptors:</para>
+ <para>
+ This declaration serves the same purpose for decorators that the <literal><Interceptors></literal>
+ declaration serves for interceptors:
+ </para>
- <itemizedlist>
- <listitem>
- <para>it enables us to specify a total ordering for all decorators
- in our system, ensuring deterministic behavior, and</para>
- </listitem>
- <listitem>
- <para>it lets us enable or disable decorator classes at deployment time.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ it enables us to specify a total ordering for all decorators in our system, ensuring deterministic
+ behavior, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>it lets us enable or disable decorator classes at deployment time.</para>
+ </listitem>
+ </itemizedlist>
- <para>Interceptors for a method are called before decorators that apply to
- that method.</para>
-
-</section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/ee.xml
===================================================================
--- doc/trunk/reference/en-US/ee.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/ee.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,186 +1,231 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="ee">
- <title>Java EE integration</title>
+ <title>Java EE integration</title>
- <para>Web Beans is fully integrated into the Java EE environment. Web Beans have
- access to Java EE resources and JPA persistence contexts. They may be used in
- Unified EL expressions in JSF and JSP pages. They may even be injected into some
- objects, such as Servlets and Message-Driven Beans, which are not Web Beans.</para>
+ <para>
+ CDI is fully integrated into the Java EE environment. Beans have access to Java EE resources and JPA persistence
+ contexts. They may be used in Unified EL expressions in JSF and JSP pages. They may even be injected into other
+ platform components, such as Servlets and Message-Driven Beans, which are not beans themselves.
+ </para>
- <section>
- <title>Injecting Java EE resources into a Web Bean</title>
+ <section>
+ <title>Injecting Java EE resources into a bean</title>
- <para>All simple and enterprise Web Beans may take advantage of Java EE dependency
- injection using <literal>@Resource</literal>, <literal>@EJB</literal> and
- <literal>@PersistenceContext</literal>. We've already seen a couple of examples of
- this, though we didn't pay much attention at the time:</para>
+ <para>
+ All managed beans may take advantage of Java EE dependency injection using <literal>@Resource</literal>,
+ <literal>@EJB</literal> and <literal>@PersistenceContext</literal>. We've already seen a couple of examples of
+ this, though we didn't pay much attention at the time:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional @Interceptor
+ <programlisting role="JAVA"><![CDATA[@Transactional @Interceptor
public class TransactionInterceptor {
+ @Resource Transaction transaction;
- @Resource Transaction transaction;
-
- @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
-
+ @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@SessionScoped
+ <programlisting role="JAVA"><![CDATA[@SessionScoped
public class Login {
-
- @Current Credentials credentials;
- @PersistenceContext EntityManager userDatabase;
-
+ @Inject Credentials credentials;
+ @PersistenceContext EntityManager userDatabase;
...
-
}]]></programlisting>
- <para>The Java EE <literal>@PostConstruct</literal> and
- <literal>@PreDestroy</literal> callbacks are also supported for all simple
- and enterprise Web Beans. The <literal>@PostConstruct</literal> method is
- called after <emphasis>all</emphasis> injection has been performed.</para>
+ <para>
+ The Java EE <literal>@PostConstruct</literal> and <literal>@PreDestroy</literal> callbacks are also supported
+ for all managed beans. The <literal>@PostConstruct</literal> method is called after <emphasis>all</emphasis>
+ injection has been performed.
+ </para>
- <para>There is one restriction to be aware of here:
- <literal>@PersistenceContext(type=EXTENDED)</literal> is not supported
- for simple Web Beans.</para>
+ <para>
+ There is one restriction to be aware of here: <literal>@PersistenceContext(type=EXTENDED)</literal> is not
+ supported for non-session beans (that's strictly a feature of stateful session beans).
+ </para>
- </section>
+ </section>
- <section>
- <title>Calling a Web Bean from a Servlet</title>
+ <section>
+ <title>Calling a bean from a Servlet</title>
- <para>It's easy to use a Web Bean from a Servlet in Java EE 6. Simply inject
- the Web Bean using Web Beans field or initializer method injection.</para>
+ <para>
+ It's easy to use a bean from a Servlet in Java EE 6. Simply inject the bean using field or initializer method
+ injection.
+ </para>
-<programlisting role="JAVA">public class Login extends HttpServlet {
+ <programlisting role="JAVA"><![CDATA[public class Login extends HttpServlet {
+ @Inject Credentials credentials;
+ @Inject Login login;
- @Current Credentials credentials;
- @Current Login login;
-
- @Override
- public void service(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- credentials.setUsername( request.getAttribute("username") ):
- credentials.setPassword( request.getAttribute("password") ):
- login.login();
- if ( login.isLoggedIn() ) {
- response.sendRedirect("/home.jsp");
- }
- else {
- response.sendRedirect("/loginError.jsp");
- }
- }
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ credentials.setUsername(request.getParameter("username")):
+ credentials.setPassword(request.getParameter("password")):
+ login.login();
+ if ( login.isLoggedIn() ) {
+ response.sendRedirect("/home.jsp");
+ }
+ else {
+ response.sendRedirect("/loginError.jsp");
+ }
+ }
-}</programlisting>
+}]]></programlisting>
- <para>The Web Beans client proxy takes care of routing method invocations from
- the Servlet to the correct instances of <literal>Credentials</literal> and
- <literal>Login</literal> for the current request and HTTP session.</para>
+ <para>
+ Since instances of Servlets are shared across all incoming threads, the bean client proxy takes care of routing
+ method invocations from the Servlet to the correct instances of <literal>Credentials</literal> and
+ <literal>Login</literal> for the current request and HTTP session.
+ </para>
- </section>
+ </section>
- <section>
- <title>Calling a Web Bean from a Message-Driven Bean</title>
+ <section>
+ <title>Calling a bean from a Message-Driven Bean</title>
- <para>Web Beans injection applies to all EJBs, even when they aren't under the
- control of the Web Bean manager (if they were obtained by direct JNDI lookup,
- or injection using <literal>@EJB</literal>, for example. In particular, you can
- use Web Beans injection in Message-Driven Beans, which are not considered Web
- Beans because you can't inject them.</para>
+ <para>
+ CDI injection applies to all EJBs, even when they aren't managed beans. In particular, you can use CDI
+ injection in Message-Driven Beans, which are not considered beans because you can't inject them and their
+ instances are not contextual (not even dependent).
+ </para>
- <para>You can even use Web Beans interceptor bindings for Message-Driven Beans.</para>
+ <para>You can even use CDI interceptor bindings for Message-Driven Beans.</para>
-<programlisting role="JAVA">@Transactional @MessageDriven
+ <programlisting role="JAVA"><![CDATA[@Transactional @MessageDriven
public class ProcessOrder implements MessageListener {
+ @Inject Inventory inventory;
+ @PersistenceContext EntityManager em;
- @Current Inventory inventory;
- @PersistenceContext EntityManager em;
+ public void onMessage(Message message) {
+ ...
+ }
+}]]></programlisting>
- public void onMessage(Message message) {
- ...
- }
-
-}</programlisting>
-
- <para>Thus, receiving messages is super-easy in a Web Beans environment. But
- beware that there is no session or conversation context available when a message
- is delivered to a Message-Driven Bean. Only <literal>@RequestScoped</literal> and
- <literal>@ApplicationScoped</literal> Web Beans are available.</para>
+ <para>
+ Thus, receiving messages is super-easy in an environment with CDI (e.g., Java EE 6). But beware that there is
+ no session or conversation context available when a message is delivered to a Message-Driven Bean. Only
+ <literal>@RequestScoped</literal> and <literal>@ApplicationScoped</literal> beans are available.
+ </para>
- <para>It's also easy to send messages using Web Beans.</para>
+ <para>
+ It's also easy to send messages using beans, if you require the full event bus of JMS rather than the
+ architecturally simpler CDI event notification facility.
+ </para>
- </section>
+ </section>
- <section id="jms">
- <title>JMS endpoints</title>
+ <section id="jms">
+ <title>JMS endpoints</title>
- <para>Sending messages using JMS can be quite complex, because of the number of
- different objects you need to deal with. For queues we have <literal>Queue</literal>,
- <literal>QueueConnectionFactory</literal>, <literal>QueueConnection</literal>,
- <literal>QueueSession</literal> and <literal>QueueSender</literal>. For topics we
- have <literal>Topic</literal>, <literal>TopicConnectionFactory</literal>,
- <literal>TopicConnection</literal>, <literal>TopicSession</literal> and
- <literal>TopicPublisher</literal>. Each of these objects has its own lifecycle and
- threading model that we need to worry about.</para>
+ <para>
+ Sending messages using JMS can be quite complex, because of the number of different objects you need to deal
+ with. For queues we have <literal>Queue</literal>, <literal>QueueConnectionFactory</literal>,
+ <literal>QueueConnection</literal>, <literal>QueueSession</literal> and <literal>QueueSender</literal>. For
+ topics we have <literal>Topic</literal>, <literal>TopicConnectionFactory</literal>,
+ <literal>TopicConnection</literal>, <literal>TopicSession</literal> and <literal>TopicPublisher</literal>. Each
+ of these objects has its own lifecycle and threading model that we need to worry about.
+ </para>
- <para>Web Beans takes care of all this for us. All we need to do is declare the
- queue or topic in <literal>web-beans.xml</literal>, specifying an associated
- binding type and connection factory.</para>
-
- <programlisting role="XML"><![CDATA[<Queue>
- <destination>java:comp/env/jms/OrderQueue</destination>
- <connectionFactory>java:comp/env/jms/QueueConnectionFactory</connectionFactory>
- <myapp:OrderProcessor/>
-</Queue>]]></programlisting>
-
- <programlisting role="XML"><![CDATA[<Topic>
- <destination>java:comp/env/jms/StockPrices</destination>
- <connectionFactory>java:comp/env/jms/TopicConnectionFactory</connectionFactory>
- <myapp:StockPrices/>
-</Topic>]]></programlisting>
+ <para>
+ You can use producer fields and methods to prepare all of these resources for injection into a bean:
+ </para>
- <para>Now we can just inject the <literal>Queue</literal>,
- <literal>QueueConnection</literal>, <literal>QueueSession</literal> or
- <literal>QueueSender</literal> for a queue, or the <literal>Topic</literal>,
- <literal>TopicConnection</literal>, <literal>TopicSession</literal> or
- <literal>TopicPublisher</literal> for a topic.</para>
+ <programlisting role="JAVA"><![CDATA[public class OrderResources {
+ @Resource(name="jms/ConnectionFactory")
+ private ConnectionFactory connectionFactory;
+
+ @Resource(name="jms/OrderQueue")
+ private Queue orderQueue;
+
+ @Produces @OrderConnection
+ public Connection createOrderConnection() throws JMSException {
+ return connectionFactory.createConnection();
+ }
+
+ public void closeOrderConnection(@Disposes @OrderConnection Connection connection)
+ throws JMSException {
+ connection.close();
+ }
+
+ @Produces @OrderSession
+ public Session createOrderSession(@OrderConnection Connection connection)
+ throws JMSException {
+ return connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
+ }
+
+ public void closeOrderSession(@Disposes @OrderSession Session session)
+ throws JMSException {
+ session.close();
+ }
+
+ @Produces @OrderMessageProducer
+ public MessageProducer createOrderMessageProducer(@OrderSession Session session)
+ throws JMSException {
+ return session.createProducer(orderQueue);
+ }
+
+ public void closeOrderMessageProducer(@Disposes @OrderMessageProducer MessageProducer producer)
+ throws JMSException {
+ producer.close();
+ }
+}]]></programlisting>
+
+ <para>
+ In this example, we can just inject the prepared <literal>MessageProducer</literal>,
+ <literal>Connection</literal> or <literal>QueueSession</literal>:
+ </para>
- <programlisting role="JAVA">@OrderProcessor QueueSender orderSender;
- at OrderProcessor QueueSession orderSession;
+ <programlisting role="JAVA"><![CDATA[@Inject Order order;
+ at Inject @OrderMessageProducer MessageProducer producer;
+ at Inject @OrderSession QueueSession orderSession;
public void sendMessage() {
- MapMessage msg = orderSession.createMapMessage();
- ...
- orderSender.send(msg);
-}</programlisting>
+ MapMessage msg = orderSession.createMapMessage();
+ msg.setLong("orderId", order.getId());
+ ...
+ producer.send(msg);
+}]]></programlisting>
- <programlisting role="JAVA">@StockPrices TopicPublisher pricePublisher;
- at StockPrices TopicSession priceSession;
+ <!--
+ <programlisting role="JAVA"><![CDATA[@Inject @StockPrices TopicPublisher pricePublisher;
+ at Inject @StockPrices TopicSession priceSession;
public void sendMessage(String price) {
- pricePublisher.send( priceSession.createTextMessage(price) );
-}</programlisting>
+ pricePublisher.send(priceSession.createTextMessage(price));
+}]]></programlisting>
+ -->
- <para>The lifecycle of the injected JMS objects is completely controlled by the
- Web Bean manager.</para>
+ <para>
+ The lifecycle of the injected JMS objects is completely controlled by the container.
+ </para>
- </section>
+ </section>
- <section>
- <title>Packaging and deployment</title>
+ <section>
+ <title>Packaging and deployment</title>
- <para>Web Beans doesn't define any special deployment archive. You can package
- Web Beans in JARs, EJB-JARs or WARs — any deployment location in the application
- classpath. However, each archive that contains Web Beans must include a file named
- <literal>web-beans.xml</literal> in the <literal>META-INF</literal> or
- <literal>WEB-INF</literal> directory. The file may be empty. Web Beans deployed in
- archives that do not have a <literal>web-beans.xml</literal> file will not be available
- for use in the application.</para>
+ <para>
+ CDI doesn't define any special deployment archive. You can package beans in JARs, EJB-JARs or WARs — any
+ deployment location in the application classpath. However, the archive must be a "bean archive". That means
+ each archive that contains beans <emphasis>must</emphasis> include a file named <literal>beans.xml</literal> in
+ the <literal>META-INF</literal> directory of the classpath or <literal>WEB-INF</literal> directory of the web
+ root (for WAR archives). The file may be empty. Beans deployed in archives that do not have a
+ <literal>beans.xml</literal> file (i.e., not in a bean archive) will not be available for use in the
+ application.
+
+ </para>
- <para>For Java SE execution, Web Beans may be deployed in any location in which
- EJBs may be deployed for execution by the embeddable EJB Lite container. Again,
- each location must contain a <literal>web-beans.xml</literal> file.</para>
+ <para>
+ For Java SE execution, beans may be deployed in any location in which EJBs may be deployed for execution by the
+ embeddable EJB Lite container. Again, each location must contain a <literal>beans.xml</literal> file. (That
+ doesn't rule out the possibility of having an extention which provides support for normal Java SE execution,
+ like the Weld Java SE module).
+ </para>
- </section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/environments.xml
===================================================================
--- doc/trunk/reference/en-US/environments.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/environments.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,45 +1,44 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="environments">
- <title>Application Servers and environments supported by Web Beans</title>
+ <title>Application servers and environments supported by Weld</title>
<section>
- <title>Using Web Beans with JBoss AS</title>
+ <title>Using Weld with JBoss AS</title>
<para>
- No special configuration of your application, beyond adding either
- <literal>META-INF/beans.xml</literal> or
- <literal>WEB-INF/beans.xml</literal> is needed.
+ No special configuration is required, beyond making your application a bean archive by adding
+ <literal>META-INF/beans.xml</literal> to the classpath or <literal>WEB-INF/beans.xml</literal> to the web root.
</para>
<para>
- If you are using JBoss AS 5.0.1.GA then you'll need to install Web
- Beans as an extra. First we need to tell Web Beans where JBoss is located. Edit
- <literal>jboss-as/build.properties</literal> and set the
- <literal>jboss.home</literal> property. For example:
+ 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
+ <literal>jboss.home</literal>, as follows:
</para>
-
- <programlisting>jboss.home=/Applications/jboss-5.0.1.GA</programlisting>
-
+
+ <programlisting><![CDATA[jboss.home=/path/to/jboss-as-5.x]]></programlisting>
+
<para>
- Now we can install Web Beans:
+ Now we can install the Weld deployer from the jboss-as directory of the Weld distribution:
</para>
- <programlisting>$ cd webbeans-$VERSION/jboss-as
-$ ant update</programlisting>
+ <programlisting>$> cd jboss-as
+$> ant update</programlisting>
<note>
<para>
- A new deployer,
- <literal>webbeans.deployer</literal> is added to JBoss AS. This adds supports for
- JSR-299 deployments to JBoss AS, and allows Web Beans to query the
- EJB3 container and discover which EJBs are installed in your
- application.
+ A new deployer, <literal>weld.deployer</literal> is added to JBoss AS. This adds supports for JSR-299
+ deployments to JBoss AS, and allows Weld to query the EJB 3 container and discover which EJBs are installed
+ in your application. It also performs a necessary upgrade of the Javassist library.
</para>
</note>
<para>
- Web Beans is built into all releases of JBoss AS from 5.1 onwards.
+ Weld is built into all releases of JBoss AS from 5.2 onwards. Regardless, you can use this script to update the
+ version of Weld deployed to JBoss AS at any time.
</para>
</section>
@@ -47,29 +46,37 @@
<section>
<title>GlassFish</title>
- <para>TODO</para>
+ <para>
+ Weld is also built into GlassFish from V3 onwards. Since GlassFish V3 is the Java EE 6 reference
+ implementation, you can be confident that it will support all features of CDI. What better way
+ for it to support these features than to use the JSR-299 reference implementation? Just package up
+ your CDI application and deploy away!
+ </para>
</section>
<section>
- <title>Servlet Containers (such as Tomcat or Jetty)</title>
+ <title>Servlet containers (such as Tomcat or Jetty)</title>
- <para>Web Beans can be used in any Servlet container such as Tomcat 6.0 or Jetty 6.1.</para>
+ <para>
+ 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>
- Web Beans doesn't support deploying session beans, injection using
- <literal>@EJB</literal>, or
- <literal>@PersistenceContext</literal> or using transactional events
- in Servlet containers.
+ 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
+ EE application server.
</para>
</note>
<para>
- Web Beans should be used as a web application library in a servlet
- container. You should place <literal>webbeans-servlet.jar</literal>
- in <literal>WEB-INF/lib</literal>.
- <literal>webbeans-servlet.jar</literal> is an "uber-jar" provided for
- your convenience. Alternatively, you could use its component jars:
+ 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
+ jars:
</para>
<itemizedlist>
@@ -80,27 +87,27 @@
</listitem>
<listitem>
<para>
- <literal>webbeans-api.jar</literal>
+ <literal>weld-api.jar</literal>
</para>
</listitem>
<listitem>
<para>
- <literal>webbeans-spi.jar</literal>
+ <literal>weld-spi.jar</literal>
</para>
</listitem>
<listitem>
<para>
- <literal>webbeans-core.jar</literal>
+ <literal>weld-core.jar</literal>
</para>
</listitem>
<listitem>
<para>
- <literal>webbeans-logging.jar</literal>
+ <literal>weld-logging.jar</literal>
</para>
</listitem>
<listitem>
<para>
- <literal>webbeans-servlet-int.jar</literal>
+ <literal>weld-servlet-int.jar</literal>
</para>
</listitem>
<listitem>
@@ -121,60 +128,53 @@
</itemizedlist>
<para>
- You also need to explicitly specify the servlet listener (used to
- boot Web Beans, and control its interaction with requests) in
- <literal>web.xml</literal>:
+ You also need to explicitly specify the servlet listener (used to boot Weld, and control its interaction
+ with requests) in <literal>WEB-INF/web.xml</literal> in the web root:
</para>
<programlisting role="XML"><![CDATA[<listener>
- <listener-class>org.jboss.webbeans.environment.servlet.Listener</listener-class>
+ <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
</listener>]]></programlisting>
<section>
<title>Tomcat</title>
<para>
- Tomcat has a read-only JNDI, so Web Beans can't automatically bind
- the BeanManager. To bind the BeanManager into JNDI, you should populate
- <literal>META-INF/context.xml</literal> with the following
- contents:
+ Tomcat has a read-only JNDI, so Weld can't automatically bind the BeanManager extension SPI. To bind
+ the BeanManager into JNDI, you should populate <literal>META-INF/context.xml</literal> in the web root with
+ the following contents:
</para>
<programlisting role="XML"><![CDATA[<Context>
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
- factory="org.jboss.webbeans.resources.ManagerObjectFactory"/>
+ factory="org.jboss.weld.resources.ManagerObjectFactory"/>
</Context>]]></programlisting>
<para>
- and make it available to your deployment by adding this to
- the bottom of <literal>web.xml</literal>:
+ and make it available to your deployment by adding this to the bottom of <literal>web.xml</literal>:
</para>
<programlisting role="XML"><![CDATA[<resource-env-ref>
- <resource-env-ref-name>
- BeanManager
- </resource-env-ref-name>
+ <resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>
javax.enterprise.inject.spi.BeanManager
</resource-env-ref-type>
</resource-env-ref>]]></programlisting>
<para>
- Tomcat only allows you to bind entries to
- <literal>java:comp/env</literal>, so the BeanManager will be available
- at <literal>java:comp/env/BeanManager</literal>
+ Tomcat only allows you to bind entries to <literal>java:comp/env</literal>, so the BeanManager will be
+ available at <literal>java:comp/env/BeanManager</literal>
</para>
<para>
- Web Beans also supports Servlet injection in Tomcat. To enable this,
- place the <literal>webbeans-tomcat-support.jar</literal> in
- <literal>$TOMCAT_HOME/lib</literal>, and add the following to your
+ Weld also supports Servlet injection in Tomcat. To enable this, place the
+ <literal>weld-tomcat-support.jar</literal> in <literal>$TOMCAT_HOME/lib</literal>, and add the following to
<literal>META-INF/context.xml</literal>:
</para>
- <programlisting role="XML"><![CDATA[<Listener className="org.jboss.webbeans.environment.tomcat.WebBeansLifecycleListener"/>]]></programlisting>
+ <programlisting role="XML"><![CDATA[<Listener className="org.jboss.weld.environment.tomcat.WeldLifecycleListener"/>]]></programlisting>
</section>
@@ -182,10 +182,8 @@
<title>Jetty</title>
<para>
- Like Tomcat, Jetty has a read-only JNDI, so Web Beans can't
- automatically bind the Manager. To bind the Manager to JNDI, you
- should populate <literal>WEB-INF/jetty-env.xml</literal> with the
- following contents:
+ Like Tomcat, Jetty has a read-only JNDI, so Weld can't automatically bind the Manager. To bind the Manager
+ to JNDI, you should populate <literal>WEB-INF/jetty-env.xml</literal> with the following contents:
</para>
<programlisting role="XML"><![CDATA[<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
@@ -197,7 +195,7 @@
<Arg>
<New class="javax.naming.Reference">
<Arg>javax.enterprise.inject.spi.BeanManager</Arg>
- <Arg>org.jboss.webbeans.resources.ManagerObjectFactory</Arg>
+ <Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
<Arg/>
</New>
</Arg>
@@ -205,20 +203,18 @@
</Configure>]]></programlisting>
<para>
- Notice that Jetty doesn't not have built-in support for an
- <literal>javax.naming.spi.ObjectFactory</literal> like Tomcat, so
- it's necessary to manually create the
- <literal>javax.naming.Reference</literal> to wrap around it.
+ Notice that Jetty doesn't not have built-in support for an <literal>javax.naming.spi.ObjectFactory</literal>
+ like Tomcat, so it's necessary to manually create the <literal>javax.naming.Reference</literal> to wrap
+ around it.
</para>
<para>
- Jetty only allows you to bind entries to
- <literal>java:comp/env</literal>, so the BeanManager will be available
- at <literal>java:comp/env/BeanManager</literal>
+ Jetty only allows you to bind entries to <literal>java:comp/env</literal>, so the BeanManager will be
+ available at <literal>java:comp/env/BeanManager</literal>
</para>
<para>
- Web Beans does not currently support Servlet injection in Jetty.
+ Weld does not currently support Servlet injection in Jetty.
</para>
</section>
@@ -228,21 +224,21 @@
<section>
<title>Java SE</title>
- <para>Apart from improved integration of the Enterprise Java stack,
- Web Beans also provides a state of the art typesafe, stateful dependency
- injection framework. This is useful in a wide range of application types,
- enterprise or otherwise. To facilitate this, Web Beans provides a simple
- means for executing in the Java Standard Edition environment independently
- of any Enterprise Edition features.
+ <para>
+ Apart from improved integration of the Enterprise Java stack, Weld also provides a state of the art
+ typesafe, stateful dependency injection framework. This is useful in a wide range of application types,
+ enterprise or otherwise. To facilitate this, Weld provides a simple means for executing in the Java
+ Standard Edition environment independently of any Enterprise Edition features.
</para>
- <para>When executing in the SE environment the following features of Web
- Beans are available:</para>
+ <para>
+ When executing in the SE environment the following features of Weld are available:
+ </para>
<itemizedlist>
<listitem>
<para>
- <literal>Simple Web Beans (POJOs)</literal>
+ <literal>POJOs (no EJBs)</literal>
</para>
</listitem>
<listitem>
@@ -273,59 +269,56 @@
</itemizedlist>
<section id="weld-se">
- <title>Web Beans SE Module</title>
+ <title>CDI SE Module</title>
- <para>To make life easy for developers Web Beans provides a special module with a
- main method which will boot the Web Beans manager,
- automatically registering all simple beans found on the classpath.
- This eliminates the need for application developers to write any
- bootstrapping code. The entry point for a Web Beans SE applications
- is a simple Web Bean which observes the special <literal>ContainerInitialized</literal>
- event provided by the SE module. The command line paramters can be
- injected using either of the following:
+ <para>
+ To make life easy for developers, Weld provides a special module with a main method which will boot the CDI
+ bean manager, automatically registering all JavaBeans found on the classpath. This eliminates the need for
+ application developers to write any bootstrapping code. The entry point for a CDI SE applications is a bean
+ which observes the special <literal>ContainerInitialized</literal> event provided by the SE module. The
+ command line paramters can be injected using either of the following:
</para>
+
<programlisting role="JAVA"><![CDATA[@Parameters List<String> params;
@Parameters String[] paramsArray; // useful for compatability with existing classes]]></programlisting>
+
<para>
- Here's an example of a simple Web Beans SE application:
+ Here's an example of a simple CDI SE application:
</para>
<programlisting role="JAVA"><![CDATA[@ApplicationScoped
-public class HelloWorld
-{
- @Parameters List<String> parameters;
+public class HelloWorld {
+ @Parameters List<String> parameters;
- public void printHello( @Observes ContainerInitialized event )
- {
- System.out.println( "Hello " + parameters.get(0) );
- }
+ public void printHello(@Observes ContainerInitialized event) {
+ System.out.println("Hello " + parameters.get(0));
+ }
}]]></programlisting>
- <para>Web Beans SE applications are started by running the following
- main method.</para>
- <programlisting role="JAVA"><![CDATA[java org.jboss.webbeans.environments.se.StartMain <args>]]></programlisting>
+ <para>
+ CDI SE applications are started by running the following main method.
+ </para>
- <para>If you need to do any custom initialization of the Web Beans manager,
- for example registering custom contexts or initializing resources for
- your beans you can do so in response to the <literal>AfterBeanDiscovery</literal>
- or <literal>AfterDeploymentValidation</literal>
- events. The following example registers a custom context:</para>
-
- <programlisting role="JAVA"><![CDATA[public class PerformSetup
-{
+ <programlisting role="JAVA"><![CDATA[java org.jboss.weld.environments.se.StartMain <args>]]></programlisting>
- public void setup( @Observes AfterBeanDiscovery event )
- {
- event.addContext( ThreadContext.INSTANCE );
- }
+ <para>
+ If you need to do any custom initialization of the CDI bean manager, for example registering custom
+ contexts or initializing resources for your beans you can do so in response to the
+ <literal>AfterBeanDiscovery</literal> or <literal>AfterDeploymentValidation</literal> events. The following
+ example registers a custom context:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class PerformSetup {
+ public void setup(@Observes AfterBeanDiscovery event) {
+ event.addContext( ThreadContext.INSTANCE );
+ }
}]]></programlisting>
<note>
<para>
- The command line parameters do not become available for injection
- until the <literal>ContainerInitialized</literal> event is fired. If you
- need access to the parameters during initialization you can do so via the
- <literal>public static String[] getParameters()</literal> method in
+ The command line parameters do not become available for injection until the
+ <literal>ContainerInitialized</literal> event is fired. If you need access to the parameters during
+ initialization you can do so via the <literal>public static String[] getParameters()</literal> method in
<literal>StartMain</literal>.
</para>
</note>
@@ -334,4 +327,7 @@
</section>
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
</chapter>
Modified: doc/trunk/reference/en-US/events.xml
===================================================================
--- doc/trunk/reference/en-US/events.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/events.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,315 +1,418 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="events">
- <title>Events</title>
+ <title>Events</title>
- <para>The Web Beans event notification facility allows Web Beans to interact in a
- totally decoupled manner. Event <emphasis>producers</emphasis> raise events that
- are then delivered to event <emphasis>observers</emphasis> by the Web Bean manager.
- This basic schema might sound like the familiar observer/observable pattern, but
- there are a couple of twists:</para>
+ <para>
+ Dependency injection enables loose-coupling by allowing the implementation of the injected bean type to vary,
+ either a deployment time or runtime. Events provide a whole other level of decoupling in which there is no compile
+ time dependency between the interacting beans at all. Event <emphasis>producers</emphasis> raise (or fire) events
+ that are delivered to event <emphasis>observers</emphasis>, an exchange orchestrated by the container.
+ </para>
- <itemizedlist>
- <listitem>
- <para>not only are event producers decoupled from observers; observers are
- completely decoupled from producers,</para>
- </listitem>
- <listitem>
- <para>observers can specify a combination of "selectors" to narrow the set of
- event notifications they will receive, and</para>
- </listitem>
- <listitem>
- <para>observers can be notified immediately, or can specify that delivery
- of the event should be delayed until the end of the current transaction</para>
- </listitem>
- </itemizedlist>
+ <para>
+ CDI provides an event notification facility like the one just described. It does so using the same type safe
+ approach that you've become accustomed to with CDI's dependency injection service. In fact, it consists of all the
+ same ingredients:
+ </para>
-<section>
- <title>Event observers</title>
+ <itemizedlist>
+ <listitem><para>bean types,</para></listitem>
+ <listitem><para>qualifier annotations and</para></listitem>
+ <listitem><para>type-safe resolution.</para></listitem>
+ </itemizedlist>
- <para>An <emphasis>observer method</emphasis> is a method of a Web Bean with a
- parameter annotated <literal>@Observes</literal>.</para>
+ <para>
+ It also supports a couple of convenient features that extend beyond the basic observer/observable pattern:
+ </para>
-<programlisting role="JAVA"><![CDATA[public void onAnyDocumentEvent(@Observes Document document) { ... }]]></programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>events are qualified using annotations on the event producer object,</para>
+ </listitem>
+ <listitem>
+ <para>observers are completely decoupled from producers,</para>
+ </listitem>
+ <listitem>
+ <para>
+ observers can specify a combination of "selectors" to narrow the set of event notifications (described by
+ qualifiers) they will receive, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ observers can be notified immediately, or can specify that delivery of the event should be delayed until the
+ end of the current transaction (a very useful feature for enterprise web applications).
+ </para>
+ </listitem>
+ </itemizedlist>
- <para>The annotated parameter is called the <emphasis>event parameter</emphasis>.
- The type of the event parameter is the observed <emphasis>event type</emphasis>.
- Observer methods may also specify "selectors", which are just instances of Web Beans
- binding types. When a binding type is used as an event selector, it is called an
- <emphasis>event binding type</emphasis>.</para>
+ <para>
+ Before getting into how events are produced, let's first consider what's used as the event payload and how those
+ events are observed. We'll then hook everything together by looking at how an event is fired.
+ </para>
-<programlisting role="JAVA"><![CDATA[@BindingType
- at Target({PARAMETER, FIELD})
+ <section>
+ <title>Event payload</title>
+
+ <para>
+ The event payload carries state from producer to consumer. The event is nothing more than a plain Java
+ object--an instance of any Java type. (The only restriction is that an event type may not contain type
+ variables). No special interfaces or wrappers. In addition, that object can be assigned qualifiers, which helps
+ observers distinguish it from other events of the same type. In a way, the qualifiers are like topic selectors,
+ since they allow the observers to narrow the set of events it observes.
+ </para>
+
+ <para>
+ So what's an event qualifier? An event qualifier is just a normal qualifier, the same ones you assigned to
+ beans and injection points. Here's an example.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Target({FIELD, PARAMETER})
@Retention(RUNTIME)
-public @interface Updated { ... }]]></programlisting>
+public @interface Updated {}]]></programlisting>
- <para>We specify the event bindings of the observer method by annotating the event
- parameter:</para>
+ <para>
+ These qualifiers may or may not come into play when selecting an observer. As before, a qualifier type can have
+ members. Those members are considered as well when selecting an observer. However, only if the member is not
+ annotated <literal>@NonBinding</literal>, which causes it to be ignored by the selection process.
+ </para>
-<programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document) { ... }]]></programlisting>
+ </section>
- <para>An observer method need not specify any event bindings — in this case it
- is interested in <emphasis>all</emphasis> events of a particular type. If it does
- specify event bindings, it is only interested in events which also have those
- event bindings.</para>
+ <section>
+ <title>Event observers</title>
- <para>The observer method may have additional parameters, which are injected according
- to the usual Web Beans method parameter injection semantics:</para>
+ <para>
+ An <emphasis>observer method</emphasis> is a method of a bean with a parameter annotated
+ <literal>@Observes</literal>.
+ </para>
-<programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document, User user) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void onAnyDocumentEvent(@Observes Document document) { ... }]]></programlisting>
-</section>
+ <para>
+ The annotated parameter is called the <emphasis>event parameter</emphasis>. The type of the event parameter is
+ the observed <emphasis>event type</emphasis>, in this case <literal>Document</literal>, a class in the
+ application. Observer methods may also specify "selectors", which are just qualifiers, as just described. When
+ a qualifier is used as an event selector, it's called an <emphasis>event qualifier type</emphasis>.
+ </para>
-<section>
- <title>Event producers</title>
+ <para>
+ We specify the event qualifiers of the observer method by annotating the event parameter:
+ </para>
- <para>The event producer may obtain an <emphasis>event notifier</emphasis> object
- by injection:</para>
+ <programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document) { ... }]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Observable Event<Document> documentEvent]]></programlisting>
+ <para>
+ An observer method need not specify any event qualifiers — in this case it is interested in
+ <emphasis>all</emphasis> events of a particular type. If it does specify event bindings, it's only interested
+ in events which also have those qualifiers.
+ </para>
- <para>The <literal>@Observable</literal> annotation implicitly defines a Web Bean
- with scope <literal>@Dependent</literal> and deployment type <literal>@Standard</literal>,
- with an implementation provided by the Web Bean manager.</para>
+ <para>
+ The observer method may have <emphasis>additional</emphasis> parameters, which are injected according to the
+ usual bean method parameter injection semantics:
+ </para>
- <para>A producer raises events by calling the <literal>fire()</literal> method
- of the <literal>Event</literal> interface, passing an <emphasis>event object</emphasis>:</para>
+ <programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document, User user) { ... }]]></programlisting>
-<programlisting role="JAVA"><![CDATA[documentEvent.fire(document);]]></programlisting>
+ </section>
- <para>An event object may be an instance of any Java class that has no type
- variables or wildcard type parameters. The event will be delivered to every
- observer method that:</para>
-
- <itemizedlist>
- <listitem>
- <para>has an event parameter to which the event object is assignable, and</para>
- </listitem>
- <listitem>
- <para>specifies no event bindings.</para>
- </listitem>
- </itemizedlist>
-
- <para>The Web Bean manager simply calls all the observer methods, passing
- the event object as the value of the event parameter. If any observer method
- throws an exception, the Web Bean manager stops calling observer methods, and
- the exception is rethrown by the <literal>fire()</literal> method.</para>
+ <section>
+ <title>Event producers (Firing events)</title>
- <para>To specify a "selector", the event producer may pass an instance of the event
- binding type to the <literal>fire()</literal> method:</para>
+ <para>
+ Producers (i.e., beans) fire events using an instance of the parameterized <literal>Event</literal> interface.
+ Instances of this interface are obtained through injection:
+ </para>
-<programlisting role="JAVA"><![CDATA[documentEvent.fire( document, new AnnotationLiteral<Updated>(){} );]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Any Event<Document> documentEvent;]]></programlisting>
- <para>The helper class <literal>AnnotationLiteral</literal> makes it possible to
- instantiate binding types inline, since this is otherwise difficult to do in Java.</para>
+ <para>
+ A producer raises events by calling the <literal>fire()</literal> method of the <literal>Event</literal>
+ interface, passing an <emphasis>event object</emphasis>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[documentEvent.fire(document);]]></programlisting>
+
+ <para>
+ This particular event will be delivered to every observer method that:
+ </para>
- <para>The event will be delivered to every observer method that:</para>
+ <itemizedlist>
+ <listitem>
+ <para>has an event parameter to which the event object is assignable (i.e., <literal>Document</literal>), and</para>
+ </listitem>
+ <listitem>
+ <para>specifies no qualifier bindings.</para>
+ </listitem>
+ </itemizedlist>
- <itemizedlist>
- <listitem>
- <para>has an event parameter to which the event object is assignable, and</para>
- </listitem>
- <listitem>
- <para>does not specify any event binding <emphasis>except</emphasis> for the
- event bindings passed to <literal>fire()</literal>.</para>
- </listitem>
- </itemizedlist>
+ <para>
+ The container simply calls all the observer methods, passing the event object as the value of the event
+ parameter. If any observer method throws an exception, the container stops calling observer methods, and the
+ exception is rethrown by the <literal>fire()</literal> method.
+ </para>
- <para>Alternatively, event bindings may be specified by annotating the event notifier
- injection point:</para>
+ <para>
+ Qualifiers can be applied to an event type in one of two ways:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Observable @Updated Event<Document> documentUpdatedEvent]]></programlisting>
+ <itemizedlist>
+ <listitem>
+ <para>Add qualifier annotations to the field where <literal>Event</literal> is injected or</para>
+ </listitem>
+ <listitem>
+ <para>pass qualifier annotation literals to the <literal>select()</literal> of <literal>Event</literal>.</para>
+ </listitem>
+ </itemizedlist>
- <para>Then every event fired via this instance of <literal>Event</literal> has
- the annotated event binding. The event will be delivered to every observer method
- that:</para>
+ <para>
+ The first option is the simplest:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Inject @Updated Event<Document> documentUpdatedEvent;]]></programlisting>
+
+ <para>
+ Then, every event fired via this instance of <literal>Event</literal> has the event qualifier
+ <literal>@Updated</literal>. The event will be delivered to every observer method that:
+ </para>
- <itemizedlist>
- <listitem>
- <para>has an event parameter to which the event object is assignable, and</para>
- </listitem>
- <listitem>
- <para>does not specify any event binding <emphasis>except</emphasis> for the
- event bindings passed to <literal>fire()</literal> or the annotated event
- bindings of the event notifier injection point.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>has an event parameter to which the event object is assignable, and</para>
+ </listitem>
+ <listitem>
+ <para>
+ does not have any event qualifier <emphasis>except</emphasis> for the event qualifiers that match those
+ on the producer (in this case at the <literal>Event</literal> inject point).
+ </para>
+ </listitem>
+ </itemizedlist>
-</section>
+ <para>
+ The downside of annotating the injection point is that you can not specify the qualifiers dynamically.
+ Fortunately, CDI provides an alternative way of generating derived <literal>Event</literal> instances
+ from an <literal>Event</literal> instance using the <literal>select()</literal> method and passing
+ in qualifier annotation literals. Events can then be fired from that narrower source:
+ </para>
-<section>
- <title>Registering observers dynamically</title>
+ <programlisting role="JAVA"><![CDATA[documentEvent.select(new AnnotationLiteral<Updated>(){}).fire(document);]]></programlisting>
- <para>It's often useful to register an event observer dynamically. The application
- may implement the <literal>Observer</literal> interface and register an instance
- with an event notifier by calling the <literal>observe()</literal> method.</para>
-
- <programlisting role="JAVA"><![CDATA[documentEvent.observe( new Observer<Document>() { public void notify(Document doc) { ... } } );]]></programlisting>
-
- <para>Event binding types may be specified by the event notifier injection point or by
- passing event binding type instances to the <literal>observe()</literal> method:</para>
-
-<programlisting role="JAVA"><![CDATA[documentEvent.observe( new Observer<Document>() { public void notify(Document doc) { ... } },
- new AnnotationLiteral<Updated>(){} );]]></programlisting>
+ <para>
+ There is no difference between the firing of this event and the previous one, were the qualifiers were
+ specified at the injection point. Both events carry the <literal>@Updated</literal> qualifier.
+ </para>
-</section>
+ <para>
+ As mentioned earlier, the helper class <literal>AnnotationLiteral</literal> makes it possible to instantiate
+ qualifiers inline, since this is otherwise difficult to do in Java.
+ </para>
-<section>
- <title>Event bindings with members</title>
+ <para>
+ Event types can have multiple event qualifier types as well, assembled using any combination of annotations
+ at the injection point and annotations passed to the <literal>select()</literal> method.
+ </para>
- <para>An event binding type may have annotation members:</para>
+ </section>
-<programlisting role="JAVA"><![CDATA[@BindingType
+ <section>
+ <title>Conditional observer methods</title>
+
+ <para>
+ Normally, observer beans will be "woken up", so to speak, when an event is fired so that they can respond to
+ the event. This behavior isn't always what you want. You may be interested in delivering an event only to
+ instances of the observers that exist in one of the currently active contexts.
+ </para>
+
+ <para>
+ A conditional observer is specified by adding <literal>receive = IF_EXISTS</literal> to the
+ <literal>@Observes</literal> annotation. The default is to always receive, which means creating
+ an instance of the bean.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public void refreshOnDocumentUpdate(@Observes(receive = IF_EXISTS) @Updated Document d) { ... }]]></programlisting>
+
+ <para>
+ A dependent-scoped bean cannot be a conditional observer, essentially because it's not a contextual bean.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Event qualifiers with members</title>
+
+ <para>An event qualifier type may have annotation members:</para>
+
+<programlisting role="JAVA"><![CDATA[@Qualifier
@Target({PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface Role {
- RoleType value();
+ RoleType value();
}]]></programlisting>
- <para>The member value is used to narrow the messages delivered to the observer:</para>
+ <para>The member value is used to narrow the messages delivered to the observer:</para>
-<programlisting role="JAVA"><![CDATA[public void adminLoggedIn(@Observes @Role(ADMIN) LoggedIn event) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void adminLoggedIn(@Observes @Role(ADMIN) LoggedIn event) { ... }]]></programlisting>
- <para>Event binding type members may be specified statically by the event producer, via
- annotations at the event notifier injection point:</para>
+ <para>
+ Event qualifier type members may be specified statically by the event producer, via annotations at the event
+ notifier injection point:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Observable @Role(ADMIN) Event<LoggedIn> LoggedInEvent;}}]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Role(ADMIN) Event<LoggedIn> loggedInEvent;]]></programlisting>
- <para>Alternatively, the value of the event binding type member may be determined dynamically
- by the event producer. We start by writing an abstract subclass of <literal>AnnotationLiteral</literal>:</para>
+ <para>
+ Alternatively, the value of the event qualifier type member may be determined dynamically by the event
+ producer. We start by writing an abstract subclass of <literal>AnnotationLiteral</literal>:
+ </para>
<programlisting role="JAVA"><![CDATA[abstract class RoleBinding
- extends AnnotationLiteral<Role>
- implements Role {}]]></programlisting>
+ extends AnnotationLiteral<Role>
+ implements Role {}]]></programlisting>
- <para>The event producer passes an instance of this class to <literal>fire()</literal>:</para>
+ <para>The event producer passes an instance of this class to <literal>select()</literal>:</para>
-<programlisting role="JAVA"><![CDATA[documentEvent.fire( document, new RoleBinding() { public void value() { return user.getRole(); } } );]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[documentEvent.select(new RoleBinding() {
+ public void value() { return user.getRole(); }
+}).fire(document);]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Multiple event bindings</title>
+ <section>
+ <title>Multiple event bindings</title>
- <para>Event binding types may be combined, for example:</para>
+ <para>Event qualifier types may be combined, for example:</para>
-<programlisting role="JAVA"><![CDATA[@Observable @Blog Event<Document> blogEvent;
+ <programlisting role="JAVA"><![CDATA[@Inject @Blog Event<Document> blogEvent;
...
-if (document.isBlog()) blogEvent.fire(document, new AnnotationLiteral<Updated>(){});]]></programlisting>
+if (document.isBlog()) blogEvent.select(new AnnotationLiteral<Updated>(){}).fire(document);]]></programlisting>
- <para>When this event occurs, all of the following observer methods will be notified:</para>
+ <para>When this event occurs, all of the following observer methods will be notified:</para>
-<programlisting role="JAVA"><![CDATA[public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }]]></programlisting>
-<programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document) { ... }]]></programlisting>
-<programlisting role="JAVA"><![CDATA[public void onAnyBlogEvent(@Observes @Blog Document document) { ... }]]></programlisting>
-<programlisting role="JAVA"><![CDATA[public void onAnyDocumentEvent(@Observes Document document) { ... }}}]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void afterBlogUpdate(@Observes @Updated @Blog Document document) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void afterDocumentUpdate(@Observes @Updated Document document) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void onAnyBlogEvent(@Observes @Blog Document document) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void onAnyDocumentEvent(@Observes Document document) { ... }}}]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Transactional observers</title>
+ <section>
+ <title>Transactional observers</title>
- <para>Transactional observers receive their event notifications during the before or
- after completion phase of the transaction in which the event was raised. For example,
- the following observer method needs to refresh a query result set that is cached in
- the application context, but only when transactions that update the
- <literal>Category</literal> tree succeed:</para>
+ <para>
+ Transactional observers receive their event notifications during the before or after completion phase of the
+ transaction in which the event was raised. For example, the following observer method needs to refresh a query
+ result set that is cached in the application context, but only when transactions that update the
+ <literal>Category</literal> tree succeed:
+ </para>
-<programlisting role="JAVA"><![CDATA[public void refreshCategoryTree(@AfterTransactionSuccess @Observes CategoryUpdateEvent event) { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public void refreshCategoryTree(@Observes(during = AFTER_SUCCESS) CategoryUpdateEvent event) { ... }]]></programlisting>
- <para>There are three kinds of transactional observers:</para>
+ <para>There are five kinds of transactional observers:</para>
- <itemizedlist>
- <listitem>
- <para><literal>@AfterTransactionSuccess</literal> observers are called during
- the after completion phase of the transaction, but only if the transaction completes
- successfully</para>
- </listitem>
- <listitem>
- <para><literal>@AfterTransactionFailure</literal> observers are called during
- the after completion phase of the transaction, but only if the transaction fails to
- complete successfully</para>
- </listitem>
- <listitem>
- <para><literal>@AfterTransactionCompletion</literal> observers are called
- during the after completion phase of the transaction</para>
- </listitem>
- <listitem>
- <para><literal>@BeforeTransactionCompletion</literal> observers are called
- during the before completion phase of the transaction</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>IN_PROGESS</literal> observers are called immediately (default)
+ </para>
+ <para>
+ <literal>AFTER_SUCCESS</literal> observers are called during the after completion phase of the
+ transaction, but only if the transaction completes successfully
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_FAILURE</literal> observers are called during the after completion phase of the
+ transaction, but only if the transaction fails to complete successfully
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>AFTER_COMPLETION</literal> observers are called during the after completion phase of
+ the transaction
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>BEFORE_COMPLETION</literal> observers are called during the before completion phase
+ of the transaction
+ </para>
+ </listitem>
+ </itemizedlist>
- <para>Transactional observers are very important in a stateful object model like Web
- Beans, because state is often held for longer than a single atomic transaction.</para>
+ <para>
+ Transactional observers are very important in a stateful object model because state is often held for longer
+ than a single atomic transaction.
+ </para>
- <para>Imagine that we have cached a JPA query result set in the application scope:</para>
+ <para>Imagine that we have cached a JPA query result set in the application scope:</para>
<programlisting role="JAVA"><![CDATA[@ApplicationScoped @Singleton
public class Catalog {
- @PersistenceContext EntityManager em;
+ @PersistenceContext EntityManager em;
- List<Product> products;
+ List<Product> products;
- @Produces @Catalog
- List<Product> getCatalog() {
- if (products==null) {
- products = em.createQuery("select p from Product p where p.deleted = false")
- .getResultList();
- }
- return products;
- }
+ @Produces @Catalog
+ List<Product> getCatalog() {
+ if (products==null) {
+ products = em.createQuery("select p from Product p where p.deleted = false")
+ .getResultList();
+ }
+ return products;
+ }
}]]></programlisting>
- <para>From time to time, a <literal>Product</literal> is created or deleted. When this
- occurs, we need to refresh the <literal>Product</literal> catalog. But we should wait
- until <emphasis>after</emphasis> the transaction completes successfully before performing
- this refresh!</para>
+ <para>
+ From time to time, a <literal>Product</literal> is created or deleted. When this occurs, we need to refresh the
+ <literal>Product</literal> catalog. But we should wait until <emphasis>after</emphasis> the transaction
+ completes successfully before performing this refresh!
+ </para>
- <para>The Web Bean that creates and deletes <literal>Product</literal>s could raise
- events, for example:</para>
+ <para>
+ The bean that creates and deletes <literal>Product</literal>s could raise events, for example:
+ </para>
- <programlisting role="JAVA"><![CDATA[@Stateless
+ <programlisting role="JAVA"><![CDATA[@Stateless
public class ProductManager {
+ @PersistenceContext EntityManager em;
+ @Inject @Any Event<Product> productEvent;
- @PersistenceContext EntityManager em;
- @Observable Event<Product> productEvent;
-
- public void delete(Product product) {
- em.delete(product);
- productEvent.fire(product, new AnnotationLiteral<Deleted>(){});
- }
+ public void delete(Product product) {
+ em.delete(product);
+ productEvent.select(new AnnotationLiteral<Deleted>(){}).fire(product);
+ }
- public void persist(Product product) {
- em.persist(product);
- productEvent.fire(product, new AnnotationLiteral<Created>(){});
- }
-
- ...
-
+ public void persist(Product product) {
+ em.persist(product);
+ productEvent.select(new AnnotationLiteral<Created>(){}).fire(product);
+ }
+ ...
}]]></programlisting>
- <para>And now <literal>Catalog</literal> can observe the events after successful
- completion of the transaction:</para>
+ <para>
+ And now <literal>Catalog</literal> can observe the events after successful completion of the transaction:
+ </para>
<programlisting role="JAVA"><![CDATA[@ApplicationScoped @Singleton
public class Catalog {
-
- ...
+ ...
+ void addProduct(@Observes(during = AFTER_SUCCESS) @Created Product product) {
+ products.add(product);
+ }
- void addProduct(@AfterTransactionSuccess @Observes @Created Product product) {
- products.add(product);
- }
-
- void addProduct(@AfterTransactionSuccess @Observes @Deleted Product product) {
- products.remove(product);
- }
-
+ void addProduct(@Observes(during = AFTER_SUCCESS) @Deleted Product product) {
+ products.remove(product);
+ }
}]]></programlisting>
+ </section>
-</section>
-
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/example.xml
===================================================================
--- doc/trunk/reference/en-US/example.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/example.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -77,16 +77,14 @@
<para><literal>@LoggedIn</literal> and <literal>@UserDatabase</literal> are custom qualifier annotations:</para>
- <programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
@Target({TYPE, METHOD, PARAMETER, FIELD})
- at Documented
- at Qualifier
public @interface LoggedIn {}]]></programlisting>
- <programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
@Target({METHOD, PARAMETER, FIELD})
- at Documented
- at Qualifier
public @interface UserDatabase {}]]></programlisting>
<para>
Modified: doc/trunk/reference/en-US/extend.xml
===================================================================
--- doc/trunk/reference/en-US/extend.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/extend.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,163 +1,171 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<!-- This chapter needs *major* filling in; specifically, give an overview of how an extension plugins in -->
<chapter id="extend">
- <title>Extending Web Beans</title>
+ <title>Extending CDI through portable extensions</title>
- <para>Web Beans is intended to be a platform for frameworks, extensions and
- integration with other technologies. Therefore, Web Beans exposes a set of
- SPIs for the use of developers of portable extensions to Web Beans. For
- example, the following kinds of extensions were envisaged by the designers
- of Web Beans:</para>
+ <para>
+ CDI is intended to be a foundation for frameworks, extensions and integration with other technologies. Therefore,
+ CDI exposes a set of SPIs for the use of developers of portable extensions to CDI. For example, the following
+ kinds of extensions were envisaged by the designers of CDI:
+ </para>
- <itemizedlist>
- <listitem>
- <para>integration with Business Process Management engines,</para>
- </listitem>
- <listitem>
- <para>integration with third-party frameworks such as Spring,
- Seam, GWT or Wicket, and</para>
- </listitem>
- <listitem>
- <para>new technology based upon the Web Beans programming model.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>integration with Business Process Management engines,</para>
+ </listitem>
+ <listitem>
+ <para>
+ integration with third-party frameworks such as Spring, Seam, GWT or Wicket, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>new technology based upon the CDI programming model.</para>
+ </listitem>
+ </itemizedlist>
- <para>The nerve center for extending Web Beans is the <literal>Manager</literal>
- object.</para>
+ <para>
+ More formally, according to the spec:
+ </para>
+
+ <blockquote>
+ <para>A portable extension may integrate with the container by:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Providing its own beans, interceptors and decorators to the container
+ </para>
+ <para>
+ </para>
+ Injecting dependencies into its own objects using the dependency injection service
+ <para>
+ Providing a context implementation for a custom scope
+ </para>
+ <para>
+ Augmenting or overriding the annotation-based metadata with metadata from some other source
+ </para>
+ </listitem>
+ </itemizedlist>
+ </blockquote>
+
+ <para>
+ The nerve center for extending CDI is the <literal>BeanManager</literal> object.
+ </para>
- <section>
- <title>The <literal>Manager</literal> object</title>
+ <section>
+ <title>The <literal>BeanManager</literal> object</title>
- <para>The <literal>Manager</literal> interface lets us register and obtain
- Web Beans, interceptors, decorators, observers and contexts programatically.</para>
+ <para>
+ The <literal>BeanManager</literal> interface lets us register and obtain beans, interceptors, decorators,
+ observers and contexts programatically.
+ </para>
-<programlisting role="JAVA"><![CDATA[public interface Manager
-{
-
- public <T> Set<Bean<T>> resolveByType(Class<T> type, Annotation... bindings);
-
- public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> apiType,
- Annotation... bindings);
-
- public <T> T getInstanceByType(Class<T> type, Annotation... bindings);
-
- public <T> T getInstanceByType(TypeLiteral<T> type,
- Annotation... bindings);
-
- public Set<Bean<?>> resolveByName(String name);
-
- public Object getInstanceByName(String name);
-
- public <T> T getInstance(Bean<T> bean);
-
+<programlisting role="JAVA"><![CDATA[public interface Manager {
+ public Object getReference(Bean<?> bean, Type beanType, CreationalContext<?> ctx);
+ public Object getInjectableReference(InjectionPoint ij, CreationalContext<?> ctx);
+ public <T> CreationalContext<T> createCreationalContext(Contextual<T> contextual);
+ public Set<Bean<?>> getBeans(Type beanType, Annotation... bindings);
+ public Set<Bean<?>> getBeans(String name);
+ public <X> Bean<? extends X> getMostSpecializedBean(Bean<X> bean);
+ public Bean<?> getPassivationCapableBean(String id);
+ public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans);
+ public void validate(InjectionPoint injectionPoint);
public void fireEvent(Object event, Annotation... bindings);
-
+ public <T> Set<ObserverMethod<?, T>> resolveObserverMethods(T event, Annotation... bindings);
+ public List<Decorator<?>> resolveDecorators(Set<Type> types, Annotation... bindings);
+ public List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings);
+ public boolean isScope(Class<? extends Annotation> annotationType);
+ public boolean isNormalScope(Class<? extends Annotation> annotationType);
+ public boolean isPassivatingScope(Class<? extends Annotation> annotationType);
+ public boolean isQualifier(Class<? extends Annotation> annotationType);
+ public boolean isInterceptorBindingType(Class<? extends Annotation> annotationType);
+ public boolean isStereotype(Class<? extends Annotation> annotationType);
+ public Set<Annotation> getInterceptorBindingTypeDefinition(Class<? extends Annotation> bindingType);
+ public Set<Annotation> getStereotypeDefinition(Class<? extends Annotation> stereotype);
public Context getContext(Class<? extends Annotation> scopeType);
+ public ELResolver getELResolver();
+ public ExpressionFactory wrapExpressionFactory(ExpressionFactory expressionFactory);
+ public <T> AnnotatedType<T> createAnnotatedType(Class<T> type);
+ public <T> InjectionTarget<T> createInjectionTarget(AnnotatedType<T> type);
+}]]></programlisting>
- public Manager addContext(Context context);
+ <para>We can obtain an instance of <literal>BeanManager</literal> via injection:</para>
+
+ <programlisting role="JAVA">@Inject BeanManager beanManager</programlisting>
- public Manager addBean(Bean<?> bean);
+ <para>
+ Java EE components may obtain an instance of BeanManager from JNDI by looking up the name
+ <literal>java:comp/BeanManager</literal>. Any operation of BeanManager may be called at any time during the
+ execution of the application.
+ </para>
- public Manager addInterceptor(Interceptor interceptor);
-
- public Manager addDecorator(Decorator decorator);
-
- public <T> Manager addObserver(Observer<T> observer, Class<T> eventType,
- Annotation... bindings);
-
- public <T> Manager addObserver(Observer<T> observer, TypeLiteral<T> eventType,
- Annotation... bindings);
-
- public <T> Manager removeObserver(Observer<T> observer, Class<T> eventType,
- Annotation... bindings);
-
- public <T> Manager removeObserver(Observer<T> observer,
- TypeLiteral<T> eventType, Annotation... bindings);
-
- public <T> Set<Observer<T>> resolveObservers(T event, Annotation... bindings);
-
- public List<Interceptor> resolveInterceptors(InterceptionType type,
- Annotation... interceptorBindings);
-
- public List<Decorator> resolveDecorators(Set<Class<?>> types,
- Annotation... bindings);
-
-}]]></programlisting>
-
- <para>We can obtain an instance of <literal>Manager</literal> via injection:</para>
+ <para>Let's study some of the interfaces exposed by the <literal>BeanManager</literal>.</para>
-<programlisting role="JAVA">@Current Manager manager</programlisting>
-
- </section>
+ </section>
- <section>
- <title>The <literal>Bean</literal> class</title>
+ <section>
+ <title>The <literal>Bean</literal> class</title>
- <para>Instances of the abstract class <literal>Bean</literal> represent
- Web Beans. There is an instance of <literal>Bean</literal> registered
- with the <literal>Manager</literal> object for every Web Bean in the
- application.</para>
+ <para>
+ Instances of the interface <literal>Bean</literal> represent beans. There is an instance of
+ <literal>Bean</literal> registered with the <literal>BeanManager</literal> object for every bean in the
+ application.
+ </para>
-<programlisting role="JAVA">public abstract class Bean<T> {
+ <programlisting role="JAVA"><![CDATA[public interface class Bean<T> extends Contextual<T> {
+ public Set<Type> getTypes();
+ public Set<Annotation> getQualifiers();
+ public Class<? extends Annotation> getScope();
+ public String getName();
+ public Set<Class<? extends Annotation>> getStereotypes();
+ public Class<?> getBeanClass();
+ public boolean isAlternative();
+ public boolean isNullable();
+ public Set<InjectionPoint> getInjectionPoints();
+}]]></programlisting>
+
+ <para>
+ It's possible to implement the <literal>Bean</literal> interface and register instances by calling
+ <literal>AfterBeanDiscovery.addBean()</literal> (<literal>AfterBeanDiscovery</literal> is a built-in event type
+ that an extension can observe) to provide support for new kinds of beans, beyond those defined by the CDI
+ specification. For example, we could use the <literal>Bean</literal> interface to allow objects managed by
+ another framework to be injected into beans.
+ </para>
- private final Manager manager;
+ <para>
+ There are two subinterfaces of <literal>Bean</literal> defined by the CDI specification:
+ <literal>Interceptor</literal> and <literal>Decorator</literal>.
+ </para>
- protected Bean(Manager manager) {
- this.manager=manager;
- }
-
- protected Manager getManager() {
- return manager;
- }
-
- public abstract Set<Class> getTypes();
- public abstract Set<Annotation> getBindingTypes();
- public abstract Class<? extends Annotation> getScopeType();
- public abstract Class<? extends Annotation> getDeploymentType();
- public abstract String getName();
-
- public abstract boolean isSerializable();
- public abstract boolean isNullable();
+ </section>
- public abstract T create();
- public abstract void destroy(T instance);
+ <section>
+ <title>The <literal>Context</literal> interface</title>
-}</programlisting>
-
- <para>It's possible to extend the <literal>Bean</literal> class and
- register instances by calling <literal>Manager.addBean()</literal> to
- provide support for new kinds of Web Beans, beyond those defined by the
- Web Beans specification (simple and enterprise Web Beans, producer
- methods and JMS endpoints). For example, we could use the
- <literal>Bean</literal> class to allow objects managed by another framework
- to be injected into Web Beans.</para>
+ <para>
+ The <literal>Context</literal> interface supports addition of new scopes to CDI, or extension of the built-in
+ scopes to new environments.
+ </para>
- <para>There are two subclasses of <literal>Bean</literal> defined by the
- Web Beans specification: <literal>Interceptor</literal> and
- <literal>Decorator</literal>.</para>
-
- </section>
+<programlisting role="JAVA"><![CDATA[public interface Context {
+ public Class<? extends Annotation> getScope();
+ public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext);
+ public <T> T get(Contextual<T> contextual);
+ boolean isActive();
+}]]></programlisting>
- <section>
- <title>The <literal>Context</literal> interface</title>
+ <para>
+ For example, we might implement <literal>Context</literal> to add a business process scope to CDI, or to add
+ support for the conversation scope to an application that uses Wicket.
+ </para>
- <para>The <literal>Context</literal> interface supports addition of new
- scopes to Web Beans, or extension of the built-in scopes to new environments.</para>
-
-<programlisting role="JAVA">public interface Context {
-
- public Class<? extends Annotation> getScopeType();
-
- public <T> T get(Bean<T> bean, boolean create);
-
- boolean isActive();
-
-}</programlisting>
+ </section>
- <para>For example, we might implement <literal>Context</literal> to add a
- business process scope to Web Beans, or to add support for the conversation
- scope to an application that uses Wicket.</para>
-
- </section>
+ <!--
+ TODO finish me!
+ -->
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/extensions.xml
===================================================================
--- doc/trunk/reference/en-US/extensions.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/extensions.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,79 +1,67 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="extensions">
- <title>JSR-299 extensions available as part of Web Beans</title>
+
+ <title>CDI extensions available as part of Weld</title>
<important>
<para>
- These modules are usable on any JSR-299 implementation, not just Web
- Beans!
+ These modules are usable on any JSR-299 implementation, not just Weld!
</para>
</important>
-
<section>
- <title>Web Beans Logger</title>
+ <title>Weld Logger</title>
<para>
- Adding logging to your application is now even easier with simple injection
- of a logger object into any JSR-299 bean. Simply annotate a
- org.jboss.webbeans.log.Log type member with <emphasis>@Logger</emphasis>
- and an appropriate logger object will be injected into any instance of
- the bean.
+ Adding logging to your application is now even easier with simple injection of a logger object into any CDI
+ bean. Simply annotate a <literal>org.jboss.weld.log.Log</literal> type member with the
+ <emphasis>@Logger</emphasis> qualifier annotation and an appropriate logger object will be injected into any
+ instance of the bean.
</para>
- <programlisting role="JAVA"><![CDATA[public class Checkout {
- import org.jboss.webbeans.annotation.Logger;
- import org.jboss.webbeans.log.Log;
-
- @Logger
- private Log log;
+ <programlisting role="JAVA"><![CDATA[import org.jboss.weld.annotation.Logger;
+import org.jboss.weld.log.Log;
- void invoiceItems() {
- ShoppingCart cart;
- . . .
- log.debug("Items invoiced for {0}", cart);
- }
-
+public class Checkout {
+ private @Inject @Logger Log log;
+
+ public void invoiceItems() {
+ ShoppingCart cart;
+ ...
+ log.debug("Items invoiced for {0}", cart);
+ }
}]]></programlisting>
<para>
- The example shows how objects can be interpolated into a message. This
- interpolation is done using <emphasis>java.text.MessageFormat</emphasis>,
- so see the JavaDoc for that class for more details. In this case,
- the ShoppingCart should have implemented the <emphasis>toString()</emphasis>
- method to produce a human readable value that is meaningful in messages.
- Normally, this call would have involved evaluating cart.toString()
- with String concatenation to produce a single String argument. Thus it was
- necessary to surround the call with an if-statement using the condition
- <emphasis>log.isDebugEnabled()</emphasis> to avoid the expensive String
- concatenation if the message was not actually going to be used. However,
- when using @Logger injected logging, the conditional test can be left out
- since the object arguments are not evaluated unless the message is going to
- be logged.
+ The example shows how objects can be interpolated into a message. This interpolation is done using
+ <emphasis>java.text.MessageFormat</emphasis>, so see the JavaDoc for that class for more details. In this case,
+ the <literal>ShoppingCart</literal> should have implemented the <emphasis>toString()</emphasis> method to
+ produce a human readable value that is meaningful in messages. Normally, this call would have involved
+ evaluating cart.toString() with String concatenation to produce a single String argument. Thus it was necessary
+ to surround the call with an if-statement using the condition <emphasis>log.isDebugEnabled()</emphasis> to
+ avoid the expensive String concatenation if the message was not actually going to be used. However, when using
+ <literal>@Logger</literal>-injected logging, the conditional test can be left out since the object arguments
+ are not evaluated unless the message is going to be logged.
</para>
<note>
<para>
- You can add the Web Beans Logger to your project by including
- webbeans-logger.jar and webbeans-logging.jar to your project.
- Alternatively, express a dependency on the
- <literal>org.jboss.webbeans:webbeans-logger</literal> Maven
- artifact.
+ You can add the Weld Logger to your project by including weld-logger.jar, sl4j-api.jar and sl4j-jdk14.jar to
+ your project. Alternatively, express a dependency on the <literal>org.jboss.weld:weld-logger</literal> Maven
+ artifact.
</para>
<para>
- If you are using Web Beans as your JSR-299 implementation, there is
- no need to include <literal>webbeans-logging.jar</literal> as it's
- already included.
+ If you are using Weld as your JSR-299 implementation, there's no need to include sl4j as it's already
+ included (and used internally).
</para>
</note>
</section>
-
-<!-- <section>-->
-<!-- <title>XSD Generator for JSR-299 XML deployment descriptors</title>-->
-<!-- -->
-<!-- <para>TODO</para>-->
-<!-- </section>-->
-</chapter>
\ No newline at end of file
+ <!-- TODO surely we must have other extensions -->
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/gettingstarted.xml
===================================================================
--- doc/trunk/reference/en-US/gettingstarted.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/gettingstarted.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -766,10 +766,9 @@
<literal>@Random</literal> qualifier, used for injecting a random number:
</para>
- <programlisting role="JAVA"><![CDATA[@Target( { TYPE, METHOD, PARAMETER, FIELD })
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
- at Documented
- at Qualifier
public @interface Random {}]]></programlisting>
<para>
@@ -777,10 +776,9 @@
injecting the maximum number that can be injected:
</para>
- <programlisting role="JAVA"><![CDATA[@Target( { TYPE, METHOD, PARAMETER, FIELD })
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
- at Documented
- at Qualifier
public @interface MaxNumber {}
]]></programlisting>
@@ -1207,7 +1205,7 @@
<para>
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 life cycles. However, rather than
+ 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.
@@ -1765,7 +1763,7 @@
<para>
We've saved the most interesting bit to last, the code! The project has two simple beans,
- <literal>SentenceParser</literal> and <literal>TextTranslator</literal> and two enterprise beans,
+ <literal>SentenceParser</literal> and <literal>TextTranslator</literal> and two session beans,
<literal>TranslatorControllerBean</literal> and <literal>SentenceTranslator</literal>. You should be getting
quite familiar with what a bean looks like by now, so we'll just highlight the most interesting bits here.
</para>
Modified: doc/trunk/reference/en-US/injection.xml
===================================================================
--- doc/trunk/reference/en-US/injection.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/injection.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,613 +1,641 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="injection">
- <title>Dependency injection</title>
+ <title>Dependency injection and programmatic lookup</title>
-<para>Web Beans supports three primary mechanisms for dependency injection:</para>
+ <para>
+ One of the most significant features of CDI, certainly the most recognized, is dependency injection. But not just
+ dependency injection; type-safe dependency injection. In this chapter, you'll learn how CDI is able to leverage
+ the Java type system and annotations to build a dependency injection strategy that is both strongly typed and
+ keeps the implementation hidden from the client.
+ </para>
-<para>Constructor parameter injection:</para>
+ <section>
+ <title>Where you can @Inject</title>
-<programlisting role="JAVA"><![CDATA[public class Checkout {
+ <para>
+ Injections are declared using the JSR-330 annotation, <literal>@Inject</literal>, along with an optional set of
+ qualifiers annotations. CDI supports three primary mechanisms for dependency injection during bean
+ construction:
+ </para>
+
+ <para>
+ <emphasis>Bean constructor</emphasis> parameter injection:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class Checkout {
- private final ShoppingCart cart;
+ private final ShoppingCart cart;
- @Initializer
- public Checkout(ShoppingCart cart) {
- this.cart = cart;
- }
+ @Inject
+ public Checkout(ShoppingCart cart) {
+ this.cart = cart;
+ }
}]]></programlisting>
-<para><emphasis>Initializer</emphasis> method parameter injection:</para>
+ <note>
+ <para>
+ A bean can only have one injectable constructor.
+ </para>
+ </note>
-<programlisting role="JAVA"><![CDATA[public class Checkout {
+ <para>
+ <emphasis>Initializer</emphasis> method parameter injection:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class Checkout {
- private ShoppingCart cart;
+ private ShoppingCart cart;
- @Initializer
- void setShoppingCart(ShoppingCart cart) {
- this.cart = cart;
- }
+ @Inject
+ void setShoppingCart(ShoppingCart cart) {
+ this.cart = cart;
+ }
}]]></programlisting>
-<para>And direct field injection:</para>
+ <note>
+ <para>
+ A bean can have multiple initializer methods. If the bean is a session bean, the initializer method is not
+ required to be a business method of the session bean.
+ </para>
+ </note>
-<programlisting role="JAVA"><![CDATA[public class Checkout {
+ <para>
+ And direct field injection:
+ </para>
- private @Current ShoppingCart cart;
+ <programlisting role="JAVA"><![CDATA[public class Checkout {
+
+ private @Inject ShoppingCart cart;
}]]></programlisting>
-<para>Dependency injection always occurs when the Web Bean instance is first
-instantiated.</para>
+ <note>
+ <para>
+ Getter and setter methods are not required for field injection to work (unlike with JSF managed beans).
+ </para>
+ </note>
-<itemizedlist>
- <listitem>
- <para>First, the Web Bean manager calls the Web Bean constructor, to
- obtain an instance of the Web Bean.</para>
- </listitem>
- <listitem>
- <para>Next, the Web Bean manager initializes the values of all injected
- fields of the Web Bean.</para>
- </listitem>
- <listitem>
- <para>Next, the Web Bean manager calls all initializer methods of Web
- Bean.</para>
- </listitem>
- <listitem>
- <para>Finally, the <literal>@PostConstruct</literal> method of the Web
- Bean, if any, is called.</para>
- </listitem>
-</itemizedlist>
+ <para>
+ Dependency injection always occurs when the bean instance is first instantiated by the container.
+ </para>
-<para>Constructor parameter injection is not supported for EJB beans, since
-the EJB is instantiated by the EJB container, not the Web Bean manager.</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ First, the container calls the bean constructor (the default constructor or the one annotated @Inject), to
+ obtain an instance of the bean.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Next, the container initializes the values of all injected fields of the bean.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Next, the container calls all initializer methods of bean (the call order is not portable, don't rely on
+ it).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Finally, the <literal>@PostConstruct</literal> method of the bean is called, if defined.
+ </para>
+ </listitem>
+ </itemizedlist>
-<para>Parameters of constructors and initializer methods need not be explicitly
-annotated when the default binding type <literal>@Current</literal> applies.
-Injected fields, however, <emphasis>must</emphasis> specify a binding type, even
-when the default binding type applies. If the field does not specify a binding
-type, it will not be injected.</para>
+ <tip>
+ <para>
+ One major advantage of using constructor injection is that the bean can be made immutable.
+ </para>
+ </tip>
-<para>Producer methods also support parameter injection:</para>
+ <para>
+ Bean constructors, initializer methods and injected fields must be annotated <emphasis>@Inject</emphasis>. 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>
-<programlisting role="JAVA"><![CDATA[@Produces Checkout createCheckout(ShoppingCart cart) {
+ <para>
+ If a parameter of bean constructors and initializer methods is not explicitly annotated with a qualifier, the
+ default qualifier, <literal>@Default</literal>, is applied. The same is goes for an injected field.
+ </para>
+
+ <para>
+ CDI also supports parameter injection on methods that are invoked by the container. For instance, parameter
+ injection is supported for producer methods:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Produces Checkout createCheckout(ShoppingCart cart) {
return new Checkout(cart);
}]]></programlisting>
-<para>Finally, observer methods (which we'll meet in <xref linkend="events"/>),
-disposal methods and destructor methods all support parameter injection.</para>
+ <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"/>),
+ disposal methods and destructor methods, which all support parameter injection.
+ </para>
+ </section>
-<para>The Web Beans specification defines a procedure, called the <emphasis>typesafe
-resolution algorithm</emphasis>, that the Web Bean manager follows when identifying
-the Web 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 manager will inform
-the user immediately if a Web Bean's dependencies cannot be satisfied, by throwing
-a <literal>UnsatisfiedDependencyException</literal> or
-<literal>AmbiguousDependencyException</literal>.</para>
+ <section>
+ <title>What gets injected</title>
-<para>The purpose of this algorithm is to allow multiple Web Beans to implement the
-same API type and either:</para>
+ <para>
+ The CDI specification defines a procedure, called the <emphasis>typesafe resolution algorithm</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
+ dependencies cannot be satisfied, by throwing a <literal>UnsatisfiedDependencyException</literal> or
+ <literal>AmbiguousDependencyException</literal>.
+ </para>
-<itemizedlist>
- <listitem>
- <para>allow the client to select which implementation it requires using
- <emphasis>binding annotations</emphasis>,
- </para>
- </listitem>
- <listitem>
- <para>allow the application deployer to select which implementation is appropriate
- for a particular deployment, without changes to the client, by enabling or
- disabling <emphasis>deployment types</emphasis>, or</para>
- </listitem>
- <listitem>
- <para>allow one implementation of an API to override another implementation of
- the same API at deployment time, without changes to the client, using
- <emphasis>deployment type precedence</emphasis>.</para>
- </listitem>
-</itemizedlist>
+ <para>
+ The purpose of this algorithm is to allow multiple beans to implement the same bean type and either:
+ </para>
-<para>Let's explore how the Web Beans manager determines a Web Bean to be injected.</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ allow the client to select which implementation it requires using <emphasis>qualifier</emphasis> or
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ allow the application deployer to select which implementation is appropriate for a particular deployment,
+ without changes to the client, by enabling or disabling an <emphasis>alternative</emphasis>, or
+ </para>
+ </listitem>
+ </itemizedlist>
-<section>
- <title>Binding annotations</title>
+ <para>
+ Obviously, if you have exactly one bean of a given type, and an injection point with that same type, then bean A is
+ going to go into slot A. That's the simplest possible scenario. When you first start your application, you'll
+ likely have lots of those.
+ </para>
+
+ <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.
+ </para>
-<para>If we have more than one Web Bean that implements a particular API type, the
-injection point can specify exactly which Web Bean should be injected using a binding
-annotation. For example, there might be two implementations of
-<literal>PaymentProcessor</literal>:</para>
+ </section>
-<programlisting role="JAVA"><![CDATA[@PayByCheque
-public class ChequePaymentProcessor implements PaymentProcessor {
- public void process(Payment payment) { ... }
+ <section>
+ <title>Qualifier annotations</title>
+
+ <para>
+ If we have more than one bean that implements a particular bean type, the injection point can specify exactly
+ which bean should be injected using a qualifier annotation. For example, there might be two implementations of
+ <literal>PaymentProcessor</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Synchronous
+public class SynchronousPaymentProcessor implements PaymentProcessor {
+ public void process(Payment payment) { ... }
}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@PayByCreditCard
-public class CreditCardPaymentProcessor implements PaymentProcessor {
- public void process(Payment payment) { ... }
+ <programlisting role="JAVA"><![CDATA[@Asynchronous
+public class AsynchronousPaymentProcessor implements PaymentProcessor {
+ public void process(Payment payment) { ... }
}]]></programlisting>
-<para>Where <literal>@PayByCheque</literal> and <literal>@PayByCreditCard</literal>
-are binding annotations:</para>
+ <para>
+ Where <literal>@Synchronous</literal> and <literal>@Asynchronous</literal> are qualifier annotations:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
- at BindingType
-public @interface PayByCheque {}]]></programlisting>
+public @interface Synchronous {}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+<programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
- at BindingType
-public @interface PayByCreditCard {}]]></programlisting>
+public @interface Asynchronous {}]]></programlisting>
-<para>A client Web Bean developer uses the binding annotation to specify exactly which
-Web Bean should be injected.</para>
+ <para>
+ A client bean developer uses the qualifier annotation to specify exactly which bean should be injected.
+ </para>
-<para>Using field injection:</para>
+ <para>Using field injection:</para>
-<programlisting role="JAVA"><![CDATA[@PayByCheque PaymentProcessor chequePaymentProcessor;
- at PayByCreditCard PaymentProcessor creditCardPaymentProcessor;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Synchronous PaymentProcessor syncPaymentProcessor;
+ at Inject @Asynchronous PaymentProcessor asyncPaymentProcessor;]]></programlisting>
-<para>Using initializer method injection:</para>
+ <para>Using initializer method injection:</para>
-<programlisting role="JAVA"><![CDATA[@Initializer
-public void setPaymentProcessors(@PayByCheque PaymentProcessor chequePaymentProcessor,
- @PayByCreditCard PaymentProcessor creditCardPaymentProcessor) {
- this.chequePaymentProcessor = chequePaymentProcessor;
- this.creditCardPaymentProcessor = creditCardPaymentProcessor;
+ <programlisting role="JAVA"><![CDATA[@Inject
+public void setPaymentProcessors(@Synchronous PaymentProcessor syncPaymentProcessor,
+ @Asynchronous PaymentProcessor asyncPaymentProcessor) {
+ this.syncPaymentProcessor = syncPaymentProcessor;
+ this.asyncPaymentProcessor = asyncPaymentProcessor;
}]]></programlisting>
-<para>Or using constructor injection:</para>
+ <para>Using using constructor injection:</para>
-<programlisting role="JAVA"><![CDATA[@Initializer
-public Checkout(@PayByCheque PaymentProcessor chequePaymentProcessor,
- @PayByCreditCard PaymentProcessor creditCardPaymentProcessor) {
- this.chequePaymentProcessor = chequePaymentProcessor;
- this.creditCardPaymentProcessor = creditCardPaymentProcessor;
+ <programlisting role="JAVA"><![CDATA[@Inject
+public Checkout(@Synchronous PaymentProcessor syncPaymentProcessor,
+ @Asynchronous PaymentProcessor asyncPaymentProcessor) {
+ this.syncPaymentProcessor = syncPaymentProcessor;
+ this.asyncPaymentProcessor = asyncPaymentProcessor;
}]]></programlisting>
-<section>
- <title>Binding annotations with members</title>
+ <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
+ selected at runtime based on the state of the system:
+ </para>
- <para>Binding annotations may have members:</para>
+ <programlisting role="JAVA"><![CDATA[@Produces
+PaymentProcessor getPaymentProcessor(@Synchronous PaymentProcessor syncPaymentProcessor,
+ @Asynchronous PaymentProcessor asyncPaymentProcessor) {
+ return isSynchronous() ? syncPaymentProcessor : asyncPaymentProcessor;
+}]]></programlisting>
+
+ <para>
+ Now, you may be thinking, <emphasis>"What's the different between using a qualifier and just specifying the
+ exact implementation class you want?"</emphasis> It's important to understand that a qualifier is like an
+ extension of the interface. You could potentially implement the asynchronous payment processor differently over
+ the age of the application. However, if you use qualifier annotations to hook injection points with the bean
+ implementing that functionality, the server implementation can vary without affecting the client code. Plus,
+ you get all the benefits of using the bean's interface because you don't have a hard dependency on the
+ implementation.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- at Target({TYPE, METHOD, FIELD, PARAMETER})
- at BindingType
-public @interface PayBy {
- PaymentType value();
-}]]></programlisting>
+ <para>
+ Qualifiers will likely replace use of the factory pattern as well. The container becomes your factory and
+ the switch between implementations is dictated by the qualifier.
+ </para>
- <para>In which case, the member value is significant:</para>
+ <section>
+ <title>Qualifiers with members</title>
-<programlisting role="JAVA"><![CDATA[@PayBy(CHEQUE) PaymentProcessor chequePaymentProcessor;
- at PayBy(CREDIT_CARD) PaymentProcessor creditCardPaymentProcessor;]]></programlisting>
+ <para>
+ Annotations can have members (i.e., fields) just like regular classes. You can use these fields to furthur
+ discriminate the qualifier. This simply prevents an explosion of annotations that you have to introduce.
+ 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>
- <para>You can tell the Web Bean manager to ignore a member of a binding annotation
- type by annotating the member <literal>@NonBinding</literal>.</para>
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
+ at Target({METHOD, FIELD, PARAMETER, TYPE})
+public @interface PayBy {
+ PaymentMethod value();
+}]]></programlisting>
+
+ <para>
+ Then you select one of the possible values when you use the qualifier:
+ </para>
-</section>
+ <programlisting role="JAVA"><![CDATA[private @Inject @PayBy(CHECK) CheckPayment checkPayment;]]></programlisting>
-<section>
- <title>Combinations of binding annnotations</title>
+ <para>
+ You can tell the container to ignore a member of a qualifier type by annotating the member @NonBinding.
+ </para>
- <para>An injection point may even specify multiple binding annotations:</para>
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Retention(RUNTIME)
+ at Target({METHOD, FIELD, PARAMETER, TYPE})
+public @interface PayBy {
+ PaymentMethod value();
+ @NonBinding String comment;
+}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Asynchronous @PayByCheque PaymentProcessor paymentProcessor]]></programlisting>
+ </section>
- <para>In this case, only a Web Bean which has <emphasis>both</emphasis> binding
- annotations would be eligible for injection.</para>
+ <section>
+ <title>Combining qualifiers</title>
-</section>
+ <para>
+ Both a bean and an injection point may specify multiple qualifiers:
+ </para>
-<section>
- <title>Binding annotations and producer methods</title>
+ <programlisting role="JAVA"><![CDATA[@Synchronous @Reliable
+public class SynchronousReliablePaymentProcessor implements PaymentProcessor {
+ public void process(Payment payment) { ... }
+}]]></programlisting>
-<para>Even producer methods may specify binding annotations:</para>
+ <programlisting role="JAVA"><![CDATA[@Inject @Synchronous @Reliable PaymentProcessor syncPaymentProcessor;]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Produces
- at Asynchronous @PayByCheque
-PaymentProcessor createAsyncPaymentProcessor(@PayByCheque PaymentProcessor processor) {
- return new AsynchronousPaymentProcessor(processor);
-}]]></programlisting>
+ <para>
+ In this case, only a bean which has <emphasis>both</emphasis> qualifier annotations would be eligible for
+ injection.
+ </para>
-</section>
+ </section>
-<section>
- <title>The default binding type</title>
-
- <para>Web Beans defines a binding type <literal>@Current</literal> that is the
- default binding type for any injection point or Web Bean that does not explicitly
- specify a binding type.</para>
-
- <para>There are two common circumstances in which it is necessary to explicitly
- specify <literal>@Current</literal>:</para>
-
- <itemizedlist>
- <listitem>
- <para>on a field, in order to declare it as an injected field with the
- default binding type, and</para>
- </listitem>
- <listitem>
- <para>on a Web Bean which has another binding type in addition to the
- default binding type.</para>
- </listitem>
- </itemizedlist>
-
-</section>
-
-</section>
+ <section>
+ <title>Qualifiers on producer methods</title>
-<section id="deploymenttypes">
- <title>Deployment types</title>
+ <para>
+ Even producer methods may specify qualifier annotations:
+ </para>
- <para>All Web Beans have a <emphasis>deployment type</emphasis>. Each deployment
- type identifies a set of Web Beans that should be conditionally installed in some
- deployments of the system.</para>
+ <programlisting role="JAVA"><![CDATA[@Produces @Asynchronous PaymentProcessor getPaymentProcessor() { ... }]]></programlisting>
- <para>For example, we could define a deployment type named <literal>@Mock</literal>,
- which would identify Web Beans that should only be installed when the system executes
- inside an integration testing environment:</para>
+ <para>
+ This producer might create an asynchronous implementation powered by third party library such as Quartz
+ (though definitely check out the new scheduler support in EJB 3.1!).
+ </para>
- <programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- @Target({TYPE, METHOD})
- @DeploymentType
- public @interface Mock {}]]></programlisting>
+ </section>
- <para>Suppose we had some Web Bean that interacted with an external system to
- process payments:</para>
-
-<programlisting role="JAVA"><![CDATA[public class ExternalPaymentProcessor {
-
- public void process(Payment p) {
- ...
- }
-
-}]]></programlisting>
-
- <para>Since this Web Bean does not explicitly specify a deployment type, it has the
- default deployment type <literal>@Production</literal>.</para>
-
- <para>For integration or unit testing, the external system is slow or unavailable.
- So we would create a mock object:</para>
-
-<programlisting role="JAVA"><![CDATA[@Mock
-public class MockPaymentProcessor implements PaymentProcessor {
-
- @Override
- public void process(Payment p) {
- p.setSuccessful(true);
- }
-
-}]]></programlisting>
-
- <para>But how does the Web Bean manager determine which implementation to use in
- a particular deployment?</para>
-
-<section>
- <title>Enabling deployment types</title>
-
- <para>Web Beans defines two built-in deployment types: <literal>@Production</literal>
- and <literal>@Standard</literal>. By default, only Web Beans with the built-in deployment
- types are enabled when the system is deployed. We can identify additional deployment
- types to be enabled in a particular deployment by listing them in
- <literal>web-beans.xml</literal>.</para>
-
- <para>Going back to our example, when we deploy our integration tests, we want all
- our <literal>@Mock</literal> objects to be installed:</para>
-
-<programlisting role="XML"><![CDATA[<WebBeans>
- <Deploy>
- <Standard/>
- <Production/>
- <test:Mock/>
- </Deploy>
-</WebBeans>]]></programlisting>
-
- <para>Now the Web Bean manager will identify and install all Web Beans annotated
- <literal>@Production</literal>, <literal>@Standard</literal> or <literal>@Mock</literal>
- at deployment time.</para>
+ <section>
+ <title>The default qualifier</title>
- <para>The deployment type <literal>@Standard</literal> is used only for certain
- special Web Beans defined by the Web Beans specification. We can't use it for
- our own Web Beans, and we can't disable it.</para>
+ <para>
+ CDI defines the qualifier annotation <literal>@Default</literal> that is the default qualifier type for any
+ injection point or bean that does not explicitly specify a qualifier.
+ </para>
- <para>The deployment type <literal>@Production</literal> is the default deployment
- type for Web Beans which don't explicitly declare a deployment type, and may be
- disabled.</para>
+ <para>
+ <!-- this is a really vague point -->
+ The most common circumstance when it's necessary to explicitly specify <literal>@Default</literal> is on a bean
+ which as another qualifier in addition to the default one.
+ </para>
-</section>
+ </section>
+
+ </section>
-<section>
- <title>Deployment type precedence</title>
-
-<para>If you've been paying attention, you're probably wondering how the Web Bean
-manager decides which implementation — <literal>ExternalPaymentProcessor</literal>
-or <literal>MockPaymentProcessor</literal> — to choose. Consider what happens when
-the manager encounters this injection point:</para>
-
-<programlisting role="JAVA"><![CDATA[@Current PaymentProcessor paymentProcessor]]></programlisting>
-
-<para>There are now two Web Beans which satisfy the <literal>PaymentProcessor</literal>
-contract. Of course, we can't use a binding annotation to disambiguate, since binding
-annotations are hard-coded into the source at the injection point, and we want the
-manager to be able to decide at deployment time!</para>
-
-<para>The solution to this problem is that each deployment type has a different
-<emphasis>precedence</emphasis>. The precedence of the deployment types is determined
-by the order in which they appear in <literal>web-beans.xml</literal>. In our example,
-<literal>@Mock</literal> appears later than <literal>@Production</literal> so it
-has a higher precedence.</para>
-
-<para>Whenever the manager discovers that more than one Web Bean could satisfy the
-contract (API type plus binding annotations) specified by an injection point, it
-considers the relative precedence of the Web Beans. If one has a higher precedence
-than the others, it chooses the higher precedence Web Bean to inject. So, in our example,
-the Web Bean manager will inject <literal>MockPaymentProcessor</literal> when executing
-in our integration testing environment (which is exactly what we want).</para>
-
-<para>It's interesting to compare this facility to today's popular manager
-architectures. Various "lightweight" containers also allow conditional deployment
-of classes that exist in the classpath, but the classes that are to be deployed
-must be explicity, individually, listed in configuration code or in some XML
-configuration file. Web Beans does support Web Bean definition and configuration
-via XML, but in the common case where no complex configuration is required, deployment
-types allow a whole set of Web Beans to be enabled with a single line of XML.
-Meanwhile, a developer browsing the code can easily identify what deployment
-scenarios the Web Bean will be used in.</para>
-
-</section>
-
-<section>
- <title>Example deployment types</title>
-
-<para>Deployment types are useful for all kinds of things, here's some examples:</para>
-
-<itemizedlist>
- <listitem>
- <para><literal>@Mock</literal> and <literal>@Staging</literal> deployment types
- for testing</para>
- </listitem>
- <listitem>
- <para><literal>@AustralianTaxLaw</literal> for site-specific Web Beans</para>
- </listitem>
- <listitem>
- <para><literal>@SeamFramework</literal>, <literal>@Guice</literal> for third-party
- frameworks which build on Web Beans</para>
- </listitem>
- <listitem>
- <para><literal>@Standard</literal> for standard Web Beans defined by the Web Beans
- specification</para>
- </listitem>
-</itemizedlist>
-
-<para>I'm sure you can think of more applications...</para>
-
-</section>
-
-</section>
-
-<section>
- <title>Fixing unsatisfied dependencies</title>
+ <section>
+ <title>Fixing unsatisfied dependencies</title>
- <para>The typesafe resolution algorithm fails when, after considering the binding
- annotations and and deployment types of all Web Beans that implement the API type
- of an injection point, the Web Bean manager is unable to identify exactly one
- Web Bean to inject.</para>
+ <para>
+ The typesafe resolution algorithm fails when, after considering the qualifier annotations on all beans that
+ implement the bean type of an injection point and filtering out disabled beans (<literal>@Alternative</literal>
+ beans which are not explicitly enabled), the container is unable to identify exactly one bean to inject. The
+ container will either throw an <literal>UnsatisfiedDependencyException</literal> or
+ <literal>AmbiguousDependencyException</literal>, depending on the circumstance.
+ </para>
- <para>It's usually easy to fix an <literal>UnsatisfiedDependencyException</literal> or
- <literal>AmbiguousDependencyException</literal>.</para>
+ <para>
+ During the course of your development, your going to encounter these errors. Let's learn how to resolve them.
+ It's usually pretty easy, and a decent IDE can really help out here.
+ </para>
- <para>To fix an <literal>UnsatisfiedDependencyException</literal>, simply provide
- a Web Bean which implements the API type and has the binding types of the injection
- point — or enable the deployment type of a Web Bean that already implements the
- API type and has the binding types.</para>
+ <para>
+ To fix an <literal>UnsatisfiedDependencyException</literal>, simply provide a bean which implements the bean
+ type and has all the qualifier types of the injection point — or explicitly enable an
+ <literal>@Alternative</literal> bean that implements the bean type and has the appropriate qualifier types.
+ </para>
- <para>To fix an <literal>AmbiguousDependencyException</literal>, introduce a
- binding type to distinguish between the two implementations of the API type,
- or change the deployment type of one of the implementations so that the Web
- Bean manager can use deployment type precedence to choose between them. An
- <literal>AmbiguousDependencyException</literal> can only occur if two Web Beans
- share a binding type and have exactly the same deployment type.</para>
+ <para>
+ To fix an <literal>AmbiguousDependencyException</literal>, introduce a qualifier to distinguish between the two
+ implementations of the bean type, or disable one of two <literal>@Alternative</literal> beans that are trying
+ to occupy the same space. An <literal>AmbiguousDependencyException</literal> can only occur if two enabled
+ beans share the same qualifier types (and one bean does not specialize the other, which we'll get into
+ specialization in <xref linkend="specialization"/>).
+ </para>
+
+ <tip>
+ <para>Just remember: "There can be only one."</para>
+ </tip>
- <para>There's one more issue you need to be aware of when using dependency injection
- in Web Beans.</para>
+ <para>
+ There's one more issue you need to be aware of when using dependency injection in beans: client proxies.
+ </para>
-</section>
+ </section>
-<section>
- <title>Client proxies</title>
+ <section>
+ <title>Client proxies</title>
- <para>Clients of an injected Web Bean do not usually hold a direct reference to
- a Web Bean instance.</para>
+ <para>
+ Clients of an injected bean do not usually hold a direct reference to a bean instance, unless the bean is
+ dependent-scoped--in that case, the instance belongs to the bean.
+ </para>
- <para>Imagine that a Web Bean bound to the application scope held a direct reference
- to a Web Bean bound to the request scope. The application scoped Web Bean is shared
- between many different requests. However, each request should see a different instance
- of the request scoped Web bean!</para>
+ <para>
+ Imagine that a bean bound to the application scope held a direct reference to a bean bound to the request
+ scope. The application-scoped bean is shared between many different requests. However, each request should see
+ a different instance of the request scoped bean--the current one!
+ </para>
- <para>Now imagine that a Web Bean bound to the session scope held a direct reference
- to a Web Bean bound to the application scope. From time to time, the session context
- is serialized to disk in order to use memory more efficiently. However, the application
- scoped Web Bean instance should not be serialized along with the session scoped Web
- Bean!</para>
+ <para>
+ Now imagine that a bean bound to the session scope holds a direct reference to a bean bound to the application
+ scope. From time to time, the session context is serialized to disk in order to use memory more efficiently.
+ However, the application scoped bean instance should not be serialized along with the session scoped bean! It
+ can get that reference any time. No need to hoard it!
+ </para>
- <para>Therefore, unless a Web Bean has the default scope <literal>@Dependent</literal>,
- the Web Bean manager must indirect all injected references to the Web Bean through a
- proxy object. This <emphasis>client proxy</emphasis> is responsible for ensuring that
- the Web Bean instance that receives a method invocation is the instance that is
- associated with the current context. The client proxy also allows Web Beans bound
- to contexts such as the session context to be serialized to disk without recursively
- serializing other injected Web Beans.</para>
+ <para>
+ Therefore, unless a bean has the default scope <literal>@Dependent</literal>, the container must indirect all
+ injected references to the bean through a proxy object. This <emphasis>client proxy</emphasis> is responsible
+ for ensuring that the bean instance that receives a method invocation is the instance that is associated with
+ the current context. The client proxy also allows beans bound to contexts such as the session context to be
+ serialized to disk without recursively serializing other injected beans.
+ </para>
+
+ <note>
+ <para>
+ If you recall, Seam also boasted the ability to reference the current instance of a component. However, Seam
+ went about it differently. In Seam, the references are established prior to the method call and cleared
+ afterword using an interceptor--a process known as bijection. This model was not very friendly to multiple
+ threads sharing instances and thefore the client proxy approach was adopted in CDI instead.
+ </para>
+ </note>
- <para>Unfortunately, due to limitations of the Java language, some Java types cannot
- be proxied by the Web Bean manager. Therefore, the Web Bean manager throws an
- <literal>UnproxyableDependencyException</literal> if the type of an injection point
- cannot be proxied.</para>
+ <para>
+ Unfortunately, due to limitations of the Java language, some Java types cannot be proxied by the container. If
+ one of these types declares any scope other than <literal>@Dependent</literal>, the container throws an
+ <literal>UnproxyableDependencyException</literal> when processing its use as an injection point.
+ </para>
- <para>The following Java types cannot be proxied by the Web Bean manager:</para>
+ <para>The following Java types cannot be proxied by the container:</para>
- <itemizedlist>
- <listitem>
- <para>classes which are declared <literal>final</literal> or have a
- <literal>final</literal> method,</para>
- </listitem>
- <listitem>
- <para>classes which have no non-private constructor with no parameters, and</para>
- </listitem>
- <listitem>
- <para>arrays and primitive types.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>classes which don't have a non-private constructor with no parameters, and</para>
+ </listitem>
+ <listitem>
+ <para>
+ classes which are declared <literal>final</literal> or have a <literal>final</literal> method,
+ </para>
+ </listitem>
+ <listitem>
+ <para>arrays and primitive types.</para>
+ </listitem>
+ </itemizedlist>
- <para>It's usually very easy to fix an <literal>UnproxyableDependencyException</literal>.
- Simply add a constructor with no parameters to the injected class, introduce an interface,
- or change the scope of the injected Web Bean to <literal>@Dependent</literal>.</para>
+ <para>
+ It's usually very easy to fix an <literal>UnproxyableDependencyException</literal>. Simply add a constructor
+ with no parameters to the injected class, introduce an interface, or, if all else fails, change the scope of
+ the injected bean to <literal>@Dependent</literal>.
+ </para>
-</section>
+ </section>
-<section>
- <title>Obtaining a Web Bean by programatic lookup</title>
+ <section>
+
+ <title>Obtaining a contextual instance by programmatic lookup</title>
+
+ <para>
+ In certain situations, injection is not the most convenient way to obtain a contextual reference. For example,
+ it may not be used when:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ the bean type or qualifiers vary dynamically at runtime, or
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ depending upon the deployment, there may be no bean which satisfies the type and qualifiers, or
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ we would like to iterate over all beans of a certain type.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ In these situations, the application may obtain an instance of the interface <literal>Instance</literal>
+ parameterized for the bean type by injection:
+ </para>
- <para>The application may obtain an instance of the interface <literal>Manager</literal>
- by injection:</para>
+ <programlisting role="JAVA"><![CDATA[@Inject Instance<PaymentProcessor> paymentProcessorSource;]]></programlisting>
- <programlisting role="JAVA"><![CDATA[@Current Manager manager;]]></programlisting>
+ <para>
+ The <literal>get()</literal> method on <literal>Instance</literal> can be used to produce a contextual instance
+ of the bean programmatically.
+ </para>
- <para>The <literal>Manager</literal> object provides a set of methods for obtaining a
- Web Bean instance programatically.</para>
-
- <programlisting role="JAVA"><![CDATA[PaymentProcessor p = manager.getInstanceByType(PaymentProcessor.class);]]></programlisting>
-
- <para>Binding annotations may be specified by subclassing the helper class
- <literal>AnnotationLiteral</literal>, since it is otherwise difficult to instantiate an
- annotation type in Java.</para>
-
- <programlisting role="JAVA"><![CDATA[PaymentProcessor p = manager.getInstanceByType(PaymentProcessor.class,
- new AnnotationLiteral<CreditCard>(){});]]></programlisting>
-
- <para>If the binding type has an annotation member, we can't use an anonymous subclass of
- <literal>AnnotationLiteral</literal> — instead we'll need to create a named subclass:</para>
-
-<programlisting role="JAVA"><![CDATA[abstract class CreditCardBinding
- extends AnnotationLiteral<CreditCard>
- implements CreditCard {}]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[PaymentProcessor p = paymentProcessorSource.get()]]></programlisting>
-<programlisting role="JAVA"><![CDATA[PaymentProcessor p = manager.getInstanceByType(PaymentProcessor.class,
- new CreditCardBinding() {
- public void value() { return paymentType; }
- } );]]></programlisting>
-</section>
+ <para>
+ Of course, qualifiers can be specified at the injection point, as with a bean injection:
+ </para>
-<section>
- <title>Lifecycle callbacks, <literal>@Resource</literal>, <literal>@EJB</literal> and
- <literal>@PersistenceContext</literal></title>
+ <programlisting role="JAVA"><![CDATA[@Inject @Asynchronous Instance<PaymentProcessor> paymentProcessorSource;]]></programlisting>
- <para>Enterprise Web Beans support all the lifecycle callbacks defined by the EJB
- specification: <literal>@PostConstruct</literal>, <literal>@PreDestroy</literal>,
- <literal>@PrePassivate</literal> and <literal>@PostActivate</literal>.</para>
-
- <para>Simple Web Beans support only the <literal>@PostConstruct</literal> and
- <literal>@PreDestroy</literal> callbacks.</para>
-
- <para>Both enterprise and simple Web Beans support the use of <literal>@Resource</literal>,
- <literal>@EJB</literal> and <literal>@PersistenceContext</literal> for injection of Java
- EE resources, EJBs and JPA persistence contexts, respectively. Simple Web Beans do not
- support the use of <literal>@PersistenceContext(type=EXTENDED)</literal>.</para>
-
- <para>The <literal>@PostConstruct</literal> callback always occurs after all dependencies
- have been injected.</para>
-
-</section>
+ <para>
+ You can also select a bean dynamically from the <literal>Instance</literal> based on the bean's qualifier.
+ First, you need to add the <literal>@Any</literal> annotation at the injection point:
+ </para>
-<section>
- <title>The <literal>InjectionPoint</literal> object</title>
+ <programlisting role="JAVA"><![CDATA[@Inject @Any Instance<PaymentProcessor> paymentProcessorSource;]]></programlisting>
+
+ <para>
+ Then you specify which bean you want, based on its qualifier, using the <literal>select()</literal> method on
+ <literal>Instance</literal>. You represent a qualifier annotation in code by subclassing the helper class
+ <literal>AnnotationLiteral</literal>, since it's otherwise difficult to instantiate an annotation type in Java.
+ </para>
- <para>There are certain kinds of dependent objects — Web Beans with scope
- <literal>@Dependent</literal> — that need to know something about the object or injection
- point into which they are injected in order to be able to do what they do. For example:</para>
-
- <itemizedlist>
- <listitem>
- <para>The log category for a <literal>Logger</literal> depends upon the class of the object
- that owns it.</para>
- </listitem>
- <listitem>
- <para>Injection of a HTTP parameter or header value depends upon what parameter
- or header name was specified at the injection point.</para>
- </listitem>
- <listitem>
- <para>Injection of the result of an EL expression evaluation depends upon the
- expression that was specified at the injection point.</para>
- </listitem>
- </itemizedlist>
+ <programlisting role="JAVA"><![CDATA[PaymentProcessor p = paymentProcessorSource
+ .select(new AnnotationLiteral<Asynchronous>() {});]]></programlisting>
- <para>A Web Bean with scope <literal>@Dependent</literal> may inject an instance of
- <literal>InjectionPoint</literal> and access metadata relating to the injection point to which
- it belongs.</para>
+ <para>
+ You can choose to create a concreate type for all of your annotation literals, such as:
+ </para>
- <para>Let's look at an example. The following code is verbose, and vulnerable to refactoring
- problems:</para>
+ <programlisting role="JAVA"><![CDATA[abstract class AsynchronousQualifier
+extends AnnotationLiteral<Asynchronous> implements Asynchronous {}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[Logger log = Logger.getLogger(MyClass.class.getName());]]></programlisting>
+ <note>
+ <para>
+ The concrete is required if your qualifier has members, since an anonymous subclass cannot define members.
+ </para>
+ </note>
- <para>This clever little producer method lets you inject a JDK <literal>Logger</literal> without
- explicitly specifying the log category:</para>
+ <para>
+ Again, like with annotation definitions, the <literal>AnnotationLiteral</literal> definition may seem a bit
+ foreign at first, but it will soon become second nature as you will see it often in CDI applications.
+ </para>
-<programlisting role="JAVA"><![CDATA[class LogFactory {
+ <para>
+ Here's how you might make use the dynamic selection:
+ </para>
- @Produces Logger createLogger(InjectionPoint injectionPoint) {
- return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
- }
+ <programlisting><![CDATA[Annotation qualifier = synchronously ?
+new SynchronousQualifier() : new AsynchronousQualifier();
+PaymentProcessor p = anyPaymentProcessor.select(qualifier).get().process(payment);]]></programlisting>
-}]]></programlisting>
+ </section>
- <para>We can now write:</para>
+ <section>
+ <title>Bean names and EL lookup</title>
-<programlisting role="JAVA"><![CDATA[@Current Logger log;]]></programlisting>
+ <para>
+ You won't always be able to take advantage of the type safety that CDI provides. One of those places is the JSF
+ view. To accomodate that environment, CDI must learn to speak the binding language that view templates
+ understand. That language is the Unified EL.
+ </para>
- <para>Not convinced? Then here's a second example. To inject HTTP parameters, we need to define
- a binding type:</para>
+ <para>
+ In order to participate in the Unified EL, a bean must have a name. The old way of assigning a name to a
+ managed bean was in the faces-config.xml descriptor. This use of XML completely contradicts the approach
+ to metadata that's in CDI. Given that one of the primary goals of JSR-299 is to get JSF talking
+ with session beans (and, in turn, the rest of the Java EE platform), CDI needed to find a compromise.
+ It did in the form of the <literal>@Named</literal>.
+ </para>
-<programlisting role="JAVA"><![CDATA[@BindingType
- at Retention(RUNTIME)
- at Target({TYPE, METHOD, FIELD, PARAMETER})
-public @interface HttpParam {
- @NonBinding public String value();
-}]]></programlisting>
+ <para>
+ The <literal>@Named</literal> annotation, when added to a bean class, producer method or producer field,
+ gives an alternate way for that bean to be referenced--by a string-based name.
+ </para>
- <para>We would use this binding type at injection points as follows:</para>
+ <programlisting role="JAVA"><![CDATA[public @Named("cart") @SessionScoped class ShoppingCart {
+ ...
+}]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public @Produces @Named("items") List<Item> getItems() { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[private @Produces @Named("currentUser") User user;]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@HttpParam("username") String username;
- at HttpParam("password") String password;]]></programlisting>
+ <para>
+ Of course, you don't want to use this string-based name in your Java code, but you can use it your JSF views to
+ invoke or read state from a bean. Since a bean could be an session bean, now you can hook your JSF view
+ directly to your business component without any middle man and still keep the layers loosely coupled. Loosely
+ coupled? Yes, because names can be associated with the deployment time and runtime polymorphism that CDI
+ provides.
+ </para>
- <para>The following producer method does the work:</para>
+ <para>
+ Although JSF 2 still includes a managed bean facility, it's expected that you are now going to prefer CDI and
+ EJB as your bean container, since they provides all that JSF managed beans have and much, much more. Plus, your
+ business tier isn't tied to JSF in any way.
+ </para>
-<programlisting role="JAVA"><![CDATA[class HttpParams
+ </section>
- @Produces @HttpParam("")
- String getParamValue(ServletRequest request, InjectionPoint ip) {
- return request.getParameter(ip.getAnnotation(HttpParam.class).value());
- }
+ <section>
+ <title>Lifecycle callbacks and resource injections</title>
-}]]></programlisting>
+ <para>
+ As part of the managed bean contract, all CDI beans support the lifecycle callback methods,
+ <literal>@PostConstruct</literal> and <literal>@PreDestroy</literal> which are called after the bean is
+ initialized (and after injections take place) and before it is destroyed (when the context to which it is bound
+ ends), respectively.
+ </para>
- <para>(Note that the <literal>value()</literal> member of the <literal>HttpParam</literal>
- annotation is ignored by the Web Bean manager since it is annotated <literal>@NonBinding.</literal>)</para>
+ <para>
+ Of course, session beans also support callback methods introduced by the EJB specification, such as
+ <literal>@PrePassivate</literal> and <literal>@PostActivate</literal>.
+ </para>
-<para>The Web Bean manager provides a built-in Web Bean that implements the
-<literal>InjectionPoint</literal> interface:</para>
+ <para>
+ Managed beans also support Java EE 5-style resource injections, declared using the <literal>@Resource</literal>
+ annotation on a field. CDI beans can also inject session beans with the <literal>@EJB</literal> annotation.
+ </para>
-<programlisting role="JAVA"><![CDATA[public interface InjectionPoint {
- public Object getInstance();
- public Bean<?> getBean();
- public Member getMember():
- public <T extends Annotation> T getAnnotation(Class<T> annotation);
- public Set<T extends Annotation> getAnnotations();
-}]]></programlisting>
+ <para>
+ However, as you learned in a previous section, these injections are not fully type-safe, nor do they have the
+ semantics that CDI provides. Therefore, it's the use of <literal>@Inject</literal> for injection is preferred.
+ Relegate the resource injections to a bean that uses producer fields to mold these container-managed objects
+ into injectable beans.
+ </para>
-</section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/interceptors.xml
===================================================================
--- doc/trunk/reference/en-US/interceptors.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/interceptors.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,97 +1,106 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="interceptors">
- <title>Interceptors</title>
-<para>Web Beans re-uses the basic interceptor architecture of EJB 3.0, extending
-the functionality in two directions:</para>
+ <title>Interceptors</title>
-<itemizedlist>
- <listitem>
- <para>Any Web Bean may have interceptors, not just session beans.</para>
- </listitem>
- <listitem>
- <para>Web Beans features a more sophisticated annotation-based approach
- to binding interceptors to Web Beans.</para>
- </listitem>
-</itemizedlist>
+ <para>
+ Thanks to the managed bean specification, intereceptors are now part of the core functionality of a bean. That
+ means that you no longer need to make your class an EJB just to use interceptors!
+ </para>
-<!--section>
- <title>Method and lifecycle callback interceptors</title-->
+ <para>
+ But that doesn't mean there aren't other improvements that can be made. CDI builds on the interceptor architecture
+ of managed beans by introducing a more sophisticated, semantic, annotation-based approach to binding interceptors
+ to beans.
+ </para>
+
+ <para>
+ Interceptor functionality is defined in the interceptor specification, which the managed bean, CDI, and EJB
+ specifications all support. The interceptor specification defines two kinds of interception points:
+ </para>
- <para>The EJB specification defines two kinds of interception points:</para>
+ <itemizedlist>
+ <listitem>
+ <para>business method interception, and</para>
+ </listitem>
+ <listitem>
+ <para>lifecycle callback interception.</para>
+ </listitem>
+ </itemizedlist>
- <itemizedlist>
- <listitem>
- <para>business method interception, and</para>
- </listitem>
- <listitem>
- <para>lifecycle callback interception.</para>
- </listitem>
- </itemizedlist>
+ <para>
+ A <emphasis>business method interceptor</emphasis> applies to invocations of methods of the bean by clients of the
+ bean:
+ </para>
- <para>A <emphasis>business method interceptor</emphasis> applies to
- invocations of methods of the Web Bean by clients of the Web Bean:</para>
-
-<programlisting role="JAVA"><![CDATA[public class TransactionInterceptor {
- @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
+ <programlisting role="JAVA"><![CDATA[public class TransactionInterceptor {
+ @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}]]></programlisting>
- <para>A <emphasis>lifecycle callback interceptor</emphasis> applies to
- invocations of lifecycle callbacks by the container:</para>
+ <para>
+ A <emphasis>lifecycle callback interceptor</emphasis> applies to invocations of lifecycle callbacks by the
+ container:
+ </para>
-<programlisting role="JAVA"><![CDATA[public class DependencyInjectionInterceptor {
- @PostConstruct public void injectDependencies(InvocationContext ctx) { ... }
+ <programlisting role="JAVA"><![CDATA[public class DependencyInjectionInterceptor {
+ @PostConstruct public void injectDependencies(InvocationContext ctx) { ... }
}]]></programlisting>
- <para>An interceptor class may intercept both lifecycle callbacks and
- business methods.</para>
+ <para>
+ An interceptor class may intercept both lifecycle callbacks and business methods.
+ </para>
-<!--/section-->
+ <section>
+ <title>Interceptor bindings</title>
-<section>
- <title>Interceptor bindings</title>
+ <para>
+ Suppose we want to declare that some of our beans are transactional. The first thing we need is an
+ <emphasis>interceptor binding annotation</emphasis> to specify exactly which beans we're interested in:
+ </para>
- <para>Suppose we want to declare that some of our Web Beans are transactional.
- The first thing we need is an <emphasis>interceptor binding annotation</emphasis>
- to specify exactly which Web Beans we're interested in:</para>
-
-<programlisting role="JAVA"><![CDATA[@InterceptorBindingType
+ <programlisting role="JAVA"><![CDATA[@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Transactional {}]]></programlisting>
- <para>Now we can easily specify that our <literal>ShoppingCart</literal> is a
- transactional object:</para>
+ <para>
+ Now we can easily specify that our <literal>ShoppingCart</literal> is a transactional object:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional
+ <programlisting role="JAVA"><![CDATA[@Transactional
public class ShoppingCart { ... }]]></programlisting>
- <para>Or, if we prefer, we can specify that just one method is transactional:</para>
+ <para>
+ Or, if we prefer, we can specify that just one method is transactional:
+ </para>
-<programlisting role="JAVA"><![CDATA[public class ShoppingCart {
- @Transactional public void checkout() { ... }
+ <programlisting role="JAVA"><![CDATA[public class ShoppingCart {
+ @Transactional public void checkout() { ... }
}]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Implementing interceptors</title>
+ <section>
+ <title>Implementing interceptors</title>
- <para>That's great, but somewhere along the line we're going to have to actually
- implement the interceptor that provides this transaction management aspect. All
- we need to do is create a standard EJB interceptor, and annotate it
- <literal>@Interceptor</literal> and <literal>@Transactional</literal>.</para>
+ <para>
+ That's great, but somewhere along the line we're going to have to actually implement the interceptor that
+ provides this transaction management aspect. All we need to do is create a standard interceptor, and annotate
+ it <literal>@Interceptor</literal> and <literal>@Transactional</literal>.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional @Interceptor
+ <programlisting role="JAVA"><![CDATA[@Transactional @Interceptor
public class TransactionInterceptor {
- @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
+ @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}]]></programlisting>
- <para>All Web Beans interceptors are simple Web Beans, and can take advantage
- of dependency injection and contextual lifecycle management.</para>
+ <para>
+ All bean interceptors are beans, and can take advantage of dependency injection and contextual lifecycle
+ management.
+ </para>
-<programlisting role="JAVA"><![CDATA[@ApplicationScoped @Transactional @Interceptor
+ <programlisting role="JAVA"><![CDATA[@ApplicationScoped @Transactional @Interceptor
public class TransactionInterceptor {
@Resource Transaction transaction;
@@ -100,181 +109,230 @@
}]]></programlisting>
- <para>Multiple interceptors may use the same interceptor binding type.</para>
+ <para>
+ Multiple interceptors may use the same interceptor binding type.
+ </para>
-</section>
+ </section>
-<section>
- <title>Enabling interceptors</title>
+ <section>
+ <title>Enabling interceptors</title>
- <para>Finally, we need to <emphasis>enable</emphasis> our interceptor in
- <literal>web-beans.xml</literal>.</para>
+ <para>
+ By default, all interceptors are disabled. We need to <emphasis>enable</emphasis> our interceptor in the
+ <literal>beans.xml</literal> descriptor of a bean deployment archive. This activation only applies to beans in
+ the same archive.
+ </para>
-<programlisting role="XML"><![CDATA[<Interceptors>
- <tx:TransactionInterceptor/>
-</Interceptors>]]></programlisting>
+<programlisting role="XML"><![CDATA[<beans
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+ <interceptors>
+ <class>org.mycompany.myapp.TransactionInterceptor</class>
+ </interceptors>
+</beans>]]></programlisting>
- <para>Whoah! Why the angle bracket stew?</para>
+ <para>Whoah! Why the angle bracket stew?</para>
- <para>Well, the XML declaration solves two problems:</para>
+ <para>
+ Well, have the XML declaration is actually a <emphasis>good thing</emphasis>. It solves two problems:
+ </para>
- <itemizedlist>
- <listitem>
- <para>it enables us to specify a total ordering for all the interceptors
- in our system, ensuring deterministic behavior, and</para>
- </listitem>
- <listitem>
- <para>it lets us enable or disable interceptor classes at deployment time.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ it enables us to specify a total ordering for all the interceptors in our system, ensuring deterministic
+ behavior, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>it lets us enable or disable interceptor classes at deployment time.</para>
+ </listitem>
+ </itemizedlist>
- <para>For example, we could specify that our security interceptor runs before our
- <literal>TransactionInterceptor</literal>.</para>
+ <para>
+ For example, we could specify that our security interceptor runs before our transaction interceptor.
+ </para>
-<programlisting role="XML"><![CDATA[<Interceptors>
- <sx:SecurityInterceptor/>
- <tx:TransactionInterceptor/>
-</Interceptors>]]></programlisting>
+ <programlisting role="XML"><![CDATA[<beans
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+ <interceptors>
+ <class>org.mycompany.myapp.SecurityInterceptor</class>
+ <class>org.mycompany.myapp.TransactionInterceptor</class>
+ </interceptors>
+</beans>]]></programlisting>
-<para>Or we could turn them both off in our test environment!</para>
+ <para>Or we could turn them both off in our test environment by simply taking no action! Ah, so simple.</para>
- </section>
+ </section>
-<section>
- <title>Interceptor bindings with members</title>
+ <section>
+ <title>Interceptor bindings with members</title>
- <para>Suppose we want to add some extra information to our <literal>@Transactional</literal>
- annotation:</para>
+ <para>
+ Suppose we want to add some extra information to our <literal>@Transactional</literal> annotation:
+ </para>
-<programlisting role="JAVA"><![CDATA[@InterceptorBindingType
+ <programlisting role="JAVA"><![CDATA[@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Transactional {
- boolean requiresNew() default false;
+ boolean requiresNew() default false;
}]]></programlisting>
- <para>Web Beans will use the value of <literal>requiresNew</literal> to choose between
- two different interceptors, <literal>TransactionInterceptor</literal> and
- <literal>RequiresNewTransactionInterceptor</literal>.</para>
+ <para>
+ CDI will use the value of <literal>requiresNew</literal> to choose between two different interceptors,
+ <literal>TransactionInterceptor</literal> and <literal>RequiresNewTransactionInterceptor</literal>.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional(requiresNew=true) @Interceptor
+ <programlisting role="JAVA"><![CDATA[@Transactional(requiresNew = true) @Interceptor
public class RequiresNewTransactionInterceptor {
- @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
+ @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}]]></programlisting>
- <para>Now we can use <literal>RequiresNewTransactionInterceptor</literal> like this:</para>
+ <para>
+ Now we can use <literal>RequiresNewTransactionInterceptor</literal> like this:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional(requiresNew=true)
+ <programlisting role="JAVA"><![CDATA[@Transactional(requiresNew = true)
public class ShoppingCart { ... }]]></programlisting>
- <para>But what if we only have one interceptor and we want the manager to ignore the
- value of <literal>requiresNew</literal> when binding interceptors? We can use the
- <literal>@NonBinding</literal> annotation:</para>
+ <para>
+ But what if we only have one interceptor and we want the container to ignore the value of
+ <literal>requiresNew</literal> when binding interceptors? Perhaps this information is only useful for the
+ interceptor implementation. We can use the <literal>@NonBinding</literal> annotation:
+ </para>
-<programlisting role="JAVA"><![CDATA[@InterceptorBindingType
+ <programlisting role="JAVA"><![CDATA[@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Secure {
- @NonBinding String[] rolesAllowed() default {};
+ @NonBinding String[] rolesAllowed() default {};
}]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Multiple interceptor binding annotations</title>
+ <section>
+ <title>Multiple interceptor binding annotations</title>
- <para>Usually we use combinations of interceptor bindings types to bind multiple
- interceptors to a Web Bean. For example, the following declaration would be used
- to bind <literal>TransactionInterceptor</literal> and
- <literal>SecurityInterceptor</literal> to the same Web Bean:</para>
+ <para>
+ Usually we use combinations of interceptor bindings types to bind multiple interceptors to a bean. For example,
+ the following declaration would be used to bind <literal>TransactionInterceptor</literal> and
+ <literal>SecurityInterceptor</literal> to the same bean:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Secure(rolesAllowed="admin") @Transactional
+ <programlisting role="JAVA"><![CDATA[@Secure(rolesAllowed="admin") @Transactional
public class ShoppingCart { ... }]]></programlisting>
- <para>However, in very complex cases, an interceptor itself may specify some
- combination of interceptor binding types:</para>
+ <para>
+ However, in very complex cases, an interceptor itself may specify some combination of interceptor binding
+ types:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional @Secure @Interceptor
+ <programlisting role="JAVA"><![CDATA[@Transactional @Secure @Interceptor
public class TransactionalSecureInterceptor { ... }]]></programlisting>
- <para>Then this interceptor could be bound to the <literal>checkout()</literal>
- method using any one of the following combinations:</para>
+ <para>
+ Then this interceptor could be bound to the <literal>checkout()</literal> method using any one of the following
+ combinations:
+ </para>
-<programlisting role="JAVA"><![CDATA[public class ShoppingCart {
- @Transactional @Secure public void checkout() { ... }
+ <programlisting role="JAVA"><![CDATA[public class ShoppingCart {
+ @Transactional @Secure public void checkout() { ... }
}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Secure
+ <programlisting role="JAVA"><![CDATA[@Secure
public class ShoppingCart {
- @Transactional public void checkout() { ... }
+ @Transactional public void checkout() { ... }
}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Transactionl
+ <programlisting role="JAVA"><![CDATA[@Transactionl
public class ShoppingCart {
- @Secure public void checkout() { ... }
+ @Secure public void checkout() { ... }
}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Transactional @Secure
+ <programlisting role="JAVA"><![CDATA[@Transactional @Secure
public class ShoppingCart {
- public void checkout() { ... }
+ public void checkout() { ... }
}]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Interceptor binding type inheritance</title>
+ <section>
+ <title>Interceptor binding type inheritance</title>
- <para>One limitation of the Java language support for annotations is the lack
- of annotation inheritance. Really, annotations should have reuse built in, to
- allow this kind of thing to work:</para>
+ <para>
+ One limitation of the Java language support for annotations is the lack of annotation inheritance. Really,
+ annotations should have reuse built in, to allow this kind of thing to work:
+ </para>
-<programlisting role="JAVA"><![CDATA[public @interface Action extends Transactional, Secure { ... }]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[public @interface Action extends Transactional, Secure { ... }]]></programlisting>
- <para>Well, fortunately, Web Beans works around this missing feature of Java.
- We may annotate one interceptor binding type with other interceptor binding
- types. The interceptor bindings are transitive — any Web Bean with the first
- interceptor binding inherits the interceptor bindings declared as meta-annotations.</para>
+ <para>
+ Well, fortunately, CDI works around this missing feature of Java. We may annotate one interceptor binding type
+ with other interceptor binding types (termed a <emphasis>meta-annotation</emphasis>). The interceptor bindings
+ are transitive — any bean with the first interceptor binding inherits the interceptor bindings declared as
+ meta-annotations.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Transactional @Secure
- at InterceptorBindingType
+ <programlisting role="JAVA"><![CDATA[@Transactional @Secure
+ at InterceptorBinding
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action { ... }]]></programlisting>
- <para>Any Web Bean annotated <literal>@Action</literal> will be bound to both
- <literal>TransactionInterceptor</literal> and <literal>SecurityInterceptor</literal>.
- (And even <literal>TransactionalSecureInterceptor</literal>, if it exists.)</para>
+ <para>
+ Now, any bean annotated <literal>@Action</literal> will be bound to both
+ <literal>TransactionInterceptor</literal> and <literal>SecurityInterceptor</literal>. (And even
+ <literal>TransactionalSecureInterceptor</literal>, if it exists.)
+ </para>
-</section>
+ </section>
-<section>
- <title>Use of <literal>@Interceptors</literal></title>
+ <section>
+ <title>Use of <literal>@Interceptors</literal></title>
- <para>The <literal>@Interceptors</literal> annotation defined by the EJB specification
- is supported for both enterprise and simple Web Beans, for example:</para>
+ <para>The <literal>@Interceptors</literal> annotation defined by the interceptor specification (and used by the
+ managed bean and EJB specifications) is still supported in CDI.</para>
-<programlisting role="JAVA"><![CDATA[@Interceptors({TransactionInterceptor.class, SecurityInterceptor.class})
+ <programlisting role="JAVA"><![CDATA[@Interceptors({TransactionInterceptor.class, SecurityInterceptor.class})
public class ShoppingCart {
- public void checkout() { ... }
+ public void checkout() { ... }
}]]></programlisting>
- <para>However, this approach suffers the following drawbacks:</para>
+ <para>However, this approach suffers the following drawbacks:</para>
- <itemizedlist>
- <listitem>
- <para>the interceptor implementation is hardcoded in business code,</para>
- </listitem>
- <listitem>
- <para>interceptors may not be easily disabled at deployment time, and</para>
- </listitem>
- <listitem>
- <para>the interceptor ordering is non-global — it is determined
- by the order in which interceptors are listed at the class level.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ the interceptor implementation is hardcoded in business code,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ interceptors may not be easily disabled at deployment time, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the interceptor ordering is non-global — it is determined by the order in which interceptors are
+ listed at the class level.
+ </para>
+ </listitem>
+ </itemizedlist>
- <para>Therefore, we recommend the use of Web Beans-style interceptor bindings.</para>
+ <para>Therefore, we recommend the use of CDI-style interceptor bindings.</para>
-</section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/intro.xml
===================================================================
--- doc/trunk/reference/en-US/intro.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/intro.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,6 +1,5 @@
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
<chapter id="intro">
<title>Getting started with JSR-299 (CDI)</title>
@@ -118,9 +117,9 @@
<para>
As you've guessed, the <literal>@Inject</literal> annotation has something to do with dependency injection!
- <literal>@Inject</literal> may be applied to a constructor or method of a bean, and tells the bean manager to
- call that constructor or method when instantiating the bean. The bean manager will inject other beans it finds
- into the parameters of the constructor or method.
+ <literal>@Inject</literal> may be applied to a constructor or method of a bean, and tells the container to call
+ that constructor or method when instantiating the bean. The container will inject other beans it finds into the
+ parameters of the constructor or method.
</para>
<para>
@@ -137,12 +136,12 @@
<programlisting role="JAVA"><![CDATA[@Named @RequestScoped
public class TranslateController {
- @Inject private TextTranslator textTranslator;
+ private @Inject TextTranslator textTranslator;
private String inputText;
private String translation;
- // action method, perhaps
+ // JSF action method, perhaps
public void translate() {
translation = textTranslator.translate(inputText);
}
@@ -161,17 +160,28 @@
}]]></programlisting>
<para>
+ Alternatively, we may obtain an instance programatically from <literal>Instance</literal>
+ interface paramaterized to the bean type:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[private @Inject Instance<TextTranslator> textTranslatorSource;
+...
+public void translate() {
+ textTranslatorSource.get().translate(inputText);
+}]]></programlisting>
+
+ <para>
Notice that it isn't necessary to create a getter or setter method to inject one bean into another. CDI can
access the field directly (even if it's private!), which should help eliminate some wasteful code. The name of
the field is arbitrary. It's the field's type that determines what is injected.
- </para>
+ </para>
<para>
- At system initialization time, the bean manager must validate that exactly one bean exists which satisfies each
- injection point. In our example, if no implementation of <literal>Translator</literal> is available -- if
- the <literal>SentenceTranslator</literal> EJB was not deployed -- the bean manager would throw an
+ At system initialization time, the container must validate that exactly one bean exists which satisfies each
+ injection point. In our example, if no implementation of <literal>Translator</literal> is available -- if the
+ <literal>SentenceTranslator</literal> EJB was not deployed -- the container would throw an
<literal>UnsatisfiedDependencyException</literal>. If more than one implementation of
- <literal>Translator</literal> were available, the bean manager would throw an
+ <literal>Translator</literal> were available, the container would throw an
<literal>AmbiguousDependencyException</literal>. The same for the <literal>TextTranslator</literal> injection
point.
</para>
@@ -183,15 +193,14 @@
</section>
- <!-- mention alternatives here? -->
<section id="bean-anatomy">
<title>The anatomy of a bean</title>
<para>
A bean is an application class that contains business logic. It may be called directly from Java code, or it
may be invoked via Unified EL. A bean may access transactional resources. Dependencies between beans are
- managed automatically by the bean manager. Most beans are <emphasis>stateful</emphasis> and
- <emphasis>contextual</emphasis>. The lifecycle of a bean is always managed by the bean manager.
+ managed automatically by the container. Most beans are <emphasis>stateful</emphasis> and
+ <emphasis>contextual</emphasis>. The lifecycle of a bean is always managed by the container.
</para>
<para>
@@ -333,11 +342,11 @@
}]]></programlisting>
<para>
- The bean types alone often do not provide enough information for the bean manager to know which bean to
- inject. For instance, say you have two implementations of the <literal>PaymentProcessor</literal> interface:
+ The bean types alone often do not provide enough information for the container to know which bean to inject.
+ For instance, say you have two implementations of the <literal>PaymentProcessor</literal> interface:
<literal>CreditCardPaymentProcessor</literal> and <literal>DebitPaymentProcessor</literal>. Injecting into a
field of type <literal>PaymentProcessor</literal> introduces an ambigious condition. In these cases, the
- bean manager must rely on some client-visible semantic that is satisified by one implementation of the bean
+ container must rely on some client-visible semantic that is satisified by one implementation of the bean
type, but not by others. That semantic is called a qualifier.
</para>
@@ -348,10 +357,9 @@
Here's an example of a qualifier annotation:
</para>
- <programlisting role="JAVA"><![CDATA[@Target( { TYPE, METHOD, PARAMETER, FIELD })
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+ at Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
- at Documented
- at Qualifier
public @interface CreditCard {}]]></programlisting>
<para>
@@ -382,8 +390,8 @@
</note>
<para>
- For each injection point, the bean manager searches for a bean which satisfies the contract, meaning it
- matches the bean time and all the qualifiers. It then injects that instance.
+ For each injection point, the container searches for a bean which satisfies the contract, meaning it matches
+ the bean time and all the qualifiers. It then injects that instance.
</para>
<para>
@@ -419,7 +427,7 @@
<para>
The <emphasis>scope</emphasis> of a bean defines the lifecycle and visibility of instances created from it.
The CDI context model is extensible, accommodating arbitrary scopes. However, certain important scopes are
- built-in to the specification, and provided by the bean manager. Each scope is represented by an annotation
+ built-in to the specification, and provided by the container. Each scope is represented by an annotation
type.
</para>
@@ -444,7 +452,7 @@
<para>
If a scope is not explicitly specified, then the bean belongs to a special scope called the
<emphasis>dependent pseudo-scope</emphasis>. Beans with this scope live to serve the bean into which they
- are injected, which means their life cycle is bound to the life cycle of that object.
+ are injected, which means their lifecycle is bound to the lifecycle of that object.
</para>
<para>We'll talk more about scopes in <xref linkend="scopescontexts"/>.</para>
@@ -496,6 +504,8 @@
</section>
+ <!-- TODO the alternative section needs to be spruced up to support the text that comes in subsequent chapters. The
+ reader needs to feel confident than they would know how to create an alternative and enable it. -->
<section>
<title>Alternatives</title>
@@ -510,6 +520,12 @@
public class MockPaymentProcessor extends PaymentProcessorImpl { ... }]]></programlisting>
<para>
+ An alternative can also be declared by annotating a bean, producer method or producer fields with a
+ stereotype that has the <literal>@Alternative</literal> annotation. Stereotypes are explained in <xref
+ linkend="stereotypes"/>.
+ </para>
+
+ <para>
You then enable the alternative using the CDI deployment descriptor, META-INF/beans.xml, in the classpath
entry in which you intent to use it. An alternative must be explicitly selected in every bean deployment
archive in which the alternative should be available for injection, lookup and EL resolution.
@@ -642,7 +658,7 @@
<title>Session beans</title>
<para>
- EJB 3 session beans belong to the EJB specification. That is, the basic life cycle and semantics. Beyond
+ 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 interchangable with regular managed
beans. That means you can inject one session bean into another, a managed bean into a session bean, a
@@ -719,7 +735,7 @@
<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, life cycle management, or interceptors. The Java EE programming model makes a
+ 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.
</para>
@@ -744,9 +760,9 @@
<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 bean manager 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:
+ 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:
</para>
<itemizedlist>
Modified: doc/trunk/reference/en-US/master.xml
===================================================================
--- doc/trunk/reference/en-US/master.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/master.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,13 +1,12 @@
<?xml version='1.0' encoding="iso-8859-1"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
<book lang="en">
<xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<preface>
- <title>Note</title>
+ <title>A note about naming and nomenclature</title>
<para>
Shortly before the final draft of JSR-299 was submitted, the specification changed its name from "Web Beans" to
"Java Contexts and Dependency Injection for the Java EE platform", abbreviated CDI. For a brief period after
@@ -22,20 +21,29 @@
defining beans in XML. These features will be available as portable extensions for CDI in the Weld project, and
perhaps other implementations.
</para>
+
+ <para>
+ Note that this reference guide was started while changes were still being made to the specification. We've done
+ our best to update it for accuracy. However, if there is a conflict between what is written in this guide and
+ the specification, the specification is the authority--assume it is correct. If you believe you have found an
+ error in the specification, then report it to the JSR-299 EG.
+ </para>
</preface>
<toc/>
<part>
- <title>Contextual components, loose-coupling and strong typing</title>
+ <title>Loosely-coupled, contextual components with strong typing</title>
<xi:include href="part1.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<xi:include href="intro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="example.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="gettingstarted.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="injection.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="scopescontexts.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="producermethods.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <!-- TODO <xi:include href="producerfields.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> -->
</part>
@@ -43,6 +51,7 @@
<title>Developing loosely-coupled code</title>
<xi:include href="part2.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<xi:include href="interceptors.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="decorators.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
@@ -56,7 +65,6 @@
<xi:include href="stereotypes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="specialization.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
@@ -79,12 +87,14 @@
<xi:include href="environments.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="extensions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <!--
+ <xi:include href="xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ -->
<xi:include href="viewlayers.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="ri-spi.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
- <xi:include href="ri-spi.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
<!--
vim:et:ts=3:sw=3:tw=120
-->
Modified: doc/trunk/reference/en-US/next.xml
===================================================================
--- doc/trunk/reference/en-US/next.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/next.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,21 +1,33 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
-<chapter>
- <title>Next steps</title>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="next">
+ <title>Next steps</title>
- <para>Because Web Beans is so new, there's not yet a lot of information
- available online.</para> !
+ <para>
+ Because CDI is so new, there's not yet a lot of information available online. That will change over time.
+ Regardless, the CDI specification remains the authority for information on CDI. The spec is kept at around 100
+ pages intentionally easy to read (don't worry, it's not like your Blue-ray player manual). You may be especially
+ interested in reading it since it covers many details that we've skipped over. The spec is available on the
+ <ulink src="http://jcp.org/en/jsr/detail?id=299">JSR-299 page</ulink> at the JCP website. Updates to the spec are
+ also frequently mailed to the <ulink src="https://lists.jboss.org/mailman/listinfo/weld-dev">weld-dev</ulink>
+ mailing list.
+ </para>
- <para>Of course, the Web Beans specification is the best source of more
- information about Web Beans. The spec is about 100 pages long, only
- twice the length of this article, and almost as readable. But, of course,
- it covers many details that we've skipped over. The spec is available
- from <literal>http://jcp.org/en/jsr/detail?id=299</literal>.</para>
-
- <para>The Web Beans Reference implementation is being developed at
- <literal>http://seamframework.org/WebBeans</literal>. The RI development
- team and the Web Beans spec lead blog at <literal>http://in.relation.to</literal>.
- This article is substantially based upon a series of blog entries published
- there.</para>
-
-</chapter>
\ No newline at end of file
+ <para>
+ The CDI reference implementation, Weld, is being developed at the <ulink src="http://seamframework.org/Weld">Seam
+ project</ulink>. The RI development team and the CDI spec lead blog at <ulink
+ src="http://in.relation.to">in.relation.to</ulink>. This guide was originally based on a series of blog entries
+ published there while the specification was being developed. It's probably the best source of information about
+ the future of CDI, Weld and Seam.
+ </para>
+
+ <para>
+ We encourage you to follow the <ulink src="https://lists.jboss.org/mailman/listinfo/weld-dev">weld-dev</ulink>
+ mailing list and to get involved in <ulink src="http://seamframework.org/Weld/Development">development</ulink>. If
+ you are reading this guide, you likely have something to offer.
+ </para>
+
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/part1.xml
===================================================================
--- doc/trunk/reference/en-US/part1.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/part1.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -15,7 +15,7 @@
The <ulink src="http://jcp.org/en/jsr/detail?id=299">JSR-299</ulink> specification (CDI) defines a set of services
for the Java EE environment that make applications much easier to develop. CDI layers an enhanced lifecycle and
interaction model over existing Java component types, including Managed Beans (JavaBeans) and Enterprise JavaBeans
- (EJB session beans). As a complement to the traditional Java EE programming model, the services provide:
+ (EJB session beans). As a complement to the traditional Java EE programming model, the CDI services provide:
</para>
<itemizedlist>
Modified: doc/trunk/reference/en-US/part2.xml
===================================================================
--- doc/trunk/reference/en-US/part2.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/part2.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,54 +1,67 @@
-<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<partintro>
-<para>The first major theme of Web Beans is <emphasis>loose coupling</emphasis>.
-We've already seen three means of achieving loose coupling:</para>
+ <para>
+ The first major theme of CDI is <emphasis>loose coupling</emphasis>. We've already seen three means of achieving
+ loose coupling:
+ </para>
-<itemizedlist>
- <listitem>
- <para><emphasis>deployment types</emphasis> enable deployment
- time polymorphism,</para>
- </listitem>
- <listitem>
- <para><emphasis>producer methods</emphasis> enable runtime
- polymorphism, and</para>
- </listitem>
- <listitem>
- <para><emphasis>contextual lifecycle management</emphasis> decouples
- Web Bean lifecycles.</para>
- </listitem>
-</itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>alternatives</emphasis> enable deployment time polymorphism,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>producer methods</emphasis> enable runtime polymorphism, and</para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>contextual lifecycle management</emphasis> decouples bean lifecycles.
+ </para>
+ </listitem>
+ </itemizedlist>
-<para>These techniques serve to enable loose coupling of client and server.
-The client is no longer tightly bound to an implementation of an API, nor
-is it required to manage the lifecycle of the server object. This approach
-lets <emphasis>stateful objects interact as if they were services</emphasis>.</para>
+ <para>
+ These techniques serve to enable loose coupling of client and server. The client is no longer tightly bound to an
+ implementation of an API, nor is it required to manage the lifecycle of the server object. This approach lets
+ <emphasis>stateful objects interact as if they were services</emphasis>.
+ </para>
-<para>Loose coupling makes a system more <emphasis>dynamic</emphasis>. The
-system can respond to change in a well-defined manner. In the past, frameworks
-that attempted to provide the facilities listed above invariably did it by
-sacrificing type safety. Web Beans is the first technology that achieves this
-level of loose coupling in a typesafe way.</para>
+ <para>
+ Loose coupling makes a system more <emphasis>dynamic</emphasis>. The system can respond to change in a
+ well-defined manner. In the past, frameworks that attempted to provide the facilities listed above invariably did
+ it by sacrificing type safety (most notably by using XML descriptors). CDI is the first technology, and certainly
+ the first specification in the Java EE platform, that achieves this level of loose coupling in a typesafe way.
+ </para>
-<para>Web Beans provides three extra important facilities that further the goal
-of loose coupling:</para>
+ <para>
+ CDI provides three extra important facilities that further the goal of loose coupling:
+ </para>
-<itemizedlist>
- <listitem>
- <para><emphasis>interceptors</emphasis> decouple technical concerns from
- business logic,</para>
- </listitem>
- <listitem>
- <para><emphasis>decorators</emphasis> may be used to decouple some business
- concerns, and</para>
- </listitem>
- <listitem>
- <para><emphasis>event notifications</emphasis> decouple event producers
- from event consumers.</para>
- </listitem>
-</itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>interceptors</emphasis> decouple technical concerns from business logic,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>decorators</emphasis> may be used to decouple some business concerns, and
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>event notifications</emphasis> decouple event producers from event consumers.
+ </para>
+ </listitem>
+ </itemizedlist>
-<para>Let's explore interceptors first.</para>
+ <para>Let's explore interceptors first.</para>
-</partintro>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</partintro>
Modified: doc/trunk/reference/en-US/part3.xml
===================================================================
--- doc/trunk/reference/en-US/part3.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/part3.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,76 +1,91 @@
-<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<partintro>
- <para>The second major theme of Web Beans is <emphasis>strong typing</emphasis>.
- The information about the dependencies, interceptors and decorators of a
- Web Bean, and the information about event consumers for an event producer, is
- contained in typesafe Java constructs that may be validated by the compiler.</para>
+ <para>
+ The second major theme of Weld is <emphasis>strong typing</emphasis>. The information about the dependencies,
+ interceptors and decorators of a bean, and the information about event consumers for an event producer, is
+ contained in typesafe Java constructs that may be validated by the compiler.
+ </para>
- <para>You don't see string-based identifiers in Web Beans code, not because the
- framework is hiding them from you using clever defaulting rules — so-called
- "configuration by convention" — but because there are simply no strings there
- to begin with!</para>
+ <para>
+ You don't see string-based identifiers in CDI code, not because the framework is hiding them from you using clever
+ defaulting rules — so-called "configuration by convention" — but because there are simply no strings
+ there to begin with!
+ </para>
- <para>The obvious benefit of this approach is that <emphasis>any</emphasis> IDE can
- provide autocompletion, validation and refactoring without the need for special tooling.
- But there is a second, less-immediately-obvious, benefit. It turns out that when you
- start thinking of identifying objects, events or interceptors via annotations instead
- of names, you have an opportunity to lift the semantic level of your code.</para>
+ <para>
+ The obvious benefit of this approach is that <emphasis>any</emphasis> IDE can provide autocompletion, validation
+ and refactoring without the need for special tooling. But there is a second, less-immediately-obvious, benefit.
+ It turns out that when you start thinking of identifying objects, events or interceptors via annotations instead
+ of names, you have an opportunity to lift the semantic level of your code.
+ </para>
- <para>Web Beans encourages you develop annotations that model concepts, for
- example,</para>
+ <para>
+ CDI encourages you develop annotations that model concepts, for example,
+ </para>
- <itemizedlist>
- <listitem>
- <para><literal>@Asynchronous</literal>,</para>
- </listitem>
- <listitem>
- <para><literal>@Mock</literal>,</para>
- </listitem>
- <listitem>
- <para><literal>@Secure</literal> or</para>
- </listitem>
- <listitem>
- <para><literal>@Updated</literal>,</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para><literal>@Asynchronous</literal>,</para>
+ </listitem>
+ <listitem>
+ <para><literal>@Mock</literal>,</para>
+ </listitem>
+ <listitem>
+ <para><literal>@Secure</literal> or</para>
+ </listitem>
+ <listitem>
+ <para><literal>@Updated</literal>,</para>
+ </listitem>
+ </itemizedlist>
- <para>instead of using compound names like</para>
+ <para>instead of using compound names like</para>
- <itemizedlist>
- <listitem>
- <para><literal>asyncPaymentProcessor</literal>,</para>
- </listitem>
- <listitem>
- <para><literal>mockPaymentProcessor</literal>,</para>
- </listitem>
- <listitem>
- <para><literal>SecurityInterceptor</literal> or</para>
- </listitem>
- <listitem>
- <para><literal>DocumentUpdatedEvent</literal>.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para><literal>asyncPaymentProcessor</literal>,</para>
+ </listitem>
+ <listitem>
+ <para><literal>mockPaymentProcessor</literal>,</para>
+ </listitem>
+ <listitem>
+ <para><literal>SecurityInterceptor</literal> or</para>
+ </listitem>
+ <listitem>
+ <para><literal>DocumentUpdatedEvent</literal>.</para>
+ </listitem>
+ </itemizedlist>
- <para>The annotations are reusable. They help describe common qualities of disparate
- parts of the system. They help us categorize and understand our code. They help us
- deal with common concerns in a common way. They make our code more literate and
- more understandable.</para>
+ <para>
+ The annotations are reusable. They help describe common qualities of disparate parts of the system. They help us
+ categorize and understand our code. They help us deal with common concerns in a common way. They make our code
+ more literate and more understandable.
+ </para>
- <para>Web Beans <emphasis>stereotypes</emphasis> take this idea a step further. A
- stereotype models a common <emphasis>role</emphasis> in your application architecture.
- It encapsulates various properties of the role, including scope, interceptor bindings,
- deployment type, etc, into a single reusable package.</para>
+ <para>
+ CDI <emphasis>stereotypes</emphasis> take this idea a step further. A stereotype models a common
+ <emphasis>role</emphasis> in your application architecture. It encapsulates various properties of the role,
+ including scope, interceptor bindings, qualifiers, etc, into a single reusable package. (Of course, there is also
+ the benefit of tucking some of those annotations away).
+ </para>
- <para>Even Web Beans XML metadata is strongly typed! There's no compiler for XML, so
- Web Beans takes advantage of XML schemas to validate the Java types and attributes
- that appear in XML. This approach turns out to make the XML more literate, just like
- annotations made our Java code more literate.</para>
+ <!--
+ <para>
+ Even Web Beans XML metadata is strongly typed! There's no compiler for XML, so Web Beans takes advantage of XML
+ schemas to validate the Java types and attributes that appear in XML. This approach turns out to make the XML more
+ literate, just like annotations made our Java code more literate.
+ </para>
+ -->
- <para>We're now ready to meet some more advanced features of Web Beans. Bear in mind that
- these features exist to make our code both easier to validate and more understandable.
- Most of the time you don't ever really <emphasis>need</emphasis> to use these features,
- but if you use them wisely, you'll come to appreciate their power.</para>
+ <para>
+ We're now ready to meet some more advanced features of CDI. Bear in mind that these features exist to make our
+ code both easier to validate and more understandable. Most of the time you don't ever really
+ <emphasis>need</emphasis> to use these features, but if you use them wisely, you'll come to appreciate their
+ power.
+ </para>
-</partintro>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</partintro>
Modified: doc/trunk/reference/en-US/part4.xml
===================================================================
--- doc/trunk/reference/en-US/part4.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/part4.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,28 +1,33 @@
-<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<partintro>
- <para>The third theme of Web Beans is <emphasis>integration</emphasis>. Web
- Beans was designed to work in concert with other technologies, helping the
- application developer fit the other technologies together. Web Beans is an
- open technology. It forms a part of the Java EE ecosystem, and is itself the
- foundation for a new ecosystem of portable extensions and integration with
- existing frameworks and technologies.</para>
+ <para>
+ The third theme of CDI is <emphasis>integration</emphasis>. We've already seen how CDI helps integrate EJB and
+ JSF, allowing EJBs to be bound directly to JSF pages. That's just the beginning. The CDI services are integrated
+ into the very core of the Java EE platform. Even EJB session beans can take advantage of the dependency injection,
+ event bus, and contextual lifecycle management that CDI provides.
+ </para>
+
+ <para>
+ CDI is also designed to work in concert with technologies outside of the platform by providing integration points
+ into the Java EE platform via an SPI. This SPI positions CDI as the foundation for a new ecosystem of
+ <emphasis>portable</emphasis> extensions and integration with existing frameworks and technologies. The CDI
+ services will be able to reach a diverse collection of technologies, such as business process management (BPM)
+ engines, existing web frameworks and defacto standard component models. Of course, The Java EE platform will never
+ be able to standardize all the interesting technologies that are used in the world of Java application
+ development, but CDI makes it easier to use the technologies which are not yet part of the platform seamlessly
+ within the Java EE environment.
+ </para>
- <para>We've already seen how Web Beans helps integrate EJB and JSF, allowing
- EJBs to be bound directly to JSF pages. That's just the beginning. Web Beans
- offers the same potential to diverse other technologies, such as Business
- Process Management engines, other Web Frameworks, and third-party component
- models. The Java EE platform will never be able to standardize all the
- interesting technologies that are used in the world of Java application
- development, but Web Beans makes it easier to use the technologies which are
- not yet part of the platform seamlessly within the Java EE environment.</para>
+ <para>
+ We're about to see how to take full advantage of the Java EE platform in an application that uses CDI. We'll also
+ briefly meet a set of SPIs that are provided to support portable extensions to CDI. You might not ever need to use
+ these SPIs directly, but don't take them for granted. You will likely be using them indirectly, every time you use
+ a third-party extension, such as Seam.
+ </para>
- <para>We're about to see how to take full advantage of the Java EE platform
- in an application that uses Web Beans. We'll also briefly meet a set of SPIs
- that are provided to support portable extensions to Web Beans. You might not
- ever need to use these SPIs directly, but it's nice to know they are there if
- you need them. Most importantly, you'll take advantage of them indirectly,
- every time you use a third-party extension.</para>
-
-</partintro>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</partintro>
Modified: doc/trunk/reference/en-US/part5.xml
===================================================================
--- doc/trunk/reference/en-US/part5.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/part5.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,24 +1,28 @@
-<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE partintro PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<partintro>
<para>
- Web Beans is the reference implementation of JSR-299, and is used by JBoss
- AS and Glassfish to provide CDI services for Java Enterprise Edition
- applications. Web Beans also goes beyond the environments and APIs defined
- by the JSR-299 specification and provides support for a number of other
- environments (such as a servlet container such as Tomcat, or Java SE) and
- additional APIs and modules (such as logging, XSD generation for the
- JSR-299 XML deployment descriptors).
+ Weld is the reference implementation of JSR-299, and is used by JBoss AS and Glassfish to provide CDI services for
+ Java Enterprise Edition (Java EE) applications. Weld also goes beyond the environments and APIs defined by the
+ JSR-299 specification by providing support for a number of other environments (such as a servlet container such as
+ Tomcat, or Java SE) and additional APIs and modules (such as logging and bean utilities).
</para>
+
+ <para>
+ Some of the extensions in Weld are portable across JSR-299 implementations (like the logging and bean utilities)
+ and some are specific to Weld (such as the servlet container support). Weld also provides an SPI on which to build
+ extensions, so there are several layers involved.
+ </para>
<para>
- If you want to get started quickly using Web Beans with JBoss AS,
- GlassFish or Tomcat and experiment with one of the examples, take a look
- at <xref linkend="ri"/>.
- Otherwise read on for a exhaustive discussion of using Web Beans in all
- the environments and application servers it supports, as well the Web Beans
+ If you want to get started quickly using Weld (and, in turn, CDI) with JBoss AS, GlassFish or Tomcat and
+ experiment with one of the examples, take a look at <xref linkend="gettingstarted"/>. Otherwise read on for a
+ exhaustive discussion of using Weld in all the environments and application servers it supports and the Weld
extensions.
</para>
-</partintro>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</partintro>
Modified: doc/trunk/reference/en-US/producermethods.xml
===================================================================
--- doc/trunk/reference/en-US/producermethods.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/producermethods.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,173 +1,188 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="producermethods">
- <title>Producer methods</title>
+ <title>Producer methods</title>
- <para>Producer methods let us overcome certain limitations that arise when the Web Bean manager,
- instead of the application, is responsible for instantiating objects. They're also the easiest
- way to integrate objects which are not Web Beans into the Web Beans environment. (We'll meet
- a second approach in <xref linkend="xml"/>.)</para>
+ <para>
+ Producer methods let us overcome certain limitations that arise when a container, instead of the application, is
+ responsible for instantiating objects. They're also the easiest way to integrate objects which are not beans into
+ the CDI environment. <!--(We'll meet a second approach in <xref linkend="xml"/>, a chapter covering the Weld XML
+ extension).-->
+ </para>
- <para>According to the spec:</para>
+ <para>According to the spec:</para>
- <blockquote>
+ <blockquote>
- <para>A Web Beans producer method acts as a source of objects to be injected, where:</para>
+ <para>A producer method acts as a source of objects to be injected, where:</para>
- <itemizedlist>
- <listitem>
- <para>the objects to be injected are not required to be instances of Web Beans,</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
- Web Bean constructor</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>the objects to be injected are not required to be instances of beans,</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>
- </blockquote>
+ </blockquote>
- <para>For example, producer methods let us:</para>
+ <para>For example, producer methods let us:</para>
- <itemizedlist>
- <listitem>
- <para>expose a JPA entity as a Web Bean,</para>
- </listitem>
- <listitem>
- <para>expose any JDK class as a Web Bean,</para>
- </listitem>
- <listitem>
- <para>define multiple Web Beans, with different scopes or initialization,
- for the same implementation class, or</para>
- </listitem>
- <listitem>
- <para>vary the implementation of an API type at runtime.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>expose a JPA entity as a bean,</para>
+ </listitem>
+ <listitem>
+ <para>expose any JDK class as a bean,</para>
+ </listitem>
+ <listitem>
+ <para>
+ define multiple beans, with different scopes or initialization, for the same implementation class, or
+ </para>
+ </listitem>
+ <listitem>
+ <para>vary the implementation of a bean type at runtime.</para>
+ </listitem>
+ </itemizedlist>
- <para>In particular, producer methods let us use runtime polymorphism with
- Web Beans. As we've seen, deployment types are a powerful solution to the problem
- of deployment-time polymorphism. But once the system is deployed, the Web Bean
- implementation is fixed. A producer method has no such limitation:</para>
+ <para>
+ In particular, producer methods let us use runtime polymorphism with CDI. As we've seen, alternative beans are
+ one solution to the problem of deployment-time polymorphism. But once the system is deployed, the CDI
+ implementation is fixed. A producer method has no such limitation:
+ </para>
<programlisting role="JAVA"><![CDATA[@SessionScoped
public class Preferences {
-
- private PaymentStrategyType paymentStrategy;
-
- ...
-
- @Produces @Preferred
- public PaymentStrategy getPaymentStrategy() {
- switch (paymentStrategy) {
- case CREDIT_CARD: return new CreditCardPaymentStrategy();
- case CHEQUE: return new ChequePaymentStrategy();
- case PAYPAL: return new PayPalPaymentStrategy();
- default: return null;
- }
- }
-
+ private PaymentStrategyType paymentStrategy;
+ ...
+ @Produces @Preferred
+ public PaymentStrategy getPaymentStrategy() {
+ switch (paymentStrategy) {
+ case CREDIT_CARD: return new CreditCardPaymentStrategy();
+ case CHECK: return new CheckPaymentStrategy();
+ case PAYPAL: return new PayPalPaymentStrategy();
+ default: return null;
+ }
+ }
}]]></programlisting>
- <para>Consider an injection point:</para>
+ <para>Consider an injection point:</para>
-<programlisting role="JAVA"><![CDATA[@Preferred PaymentStrategy paymentStrat;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Preferred PaymentStrategy paymentStrategy;]]></programlisting>
- <para>This injection point has the same type and binding annotations as the producer
- method, so it resolves to the producer method using the usual Web Beans injection
- rules. The producer method will be called by the Web Bean manager to obtain an instance
- to service this injection point.</para>
+ <para>
+ This injection point has the same type and qualifier annotations as the producer method, so it resolves to the
+ producer method using the usual CDI injection rules. The producer method will be called by the container to
+ obtain an instance to service this injection point.
+ </para>
-<section>
- <title>Scope of a producer method</title>
+ <section>
+ <title>Scope of a producer method</title>
- <para>The scope of the producer method defaults to <literal>@Dependent</literal>, and so
- it will be called <emphasis>every time</emphasis> the Web Bean manager injects this field
- or any other field that resolves to the same producer method. Thus, there could be
- multiple instances of the <literal>PaymentStrategy</literal> object for each user session.</para>
+ <para>
+ The scope of the producer method defaults to <literal>@Dependent</literal>, and so it will be called
+ <emphasis>every time</emphasis> the container injects this field or any other field that resolves to the
+ same producer method. Thus, there could be multiple instances of the <literal>PaymentStrategy</literal>
+ object for each user session.
+ </para>
- <para>To change this behavior, we can add a <literal>@SessionScoped</literal> annotation
- to the method.</para>
+ <para>
+ To change this behavior, we can add a <literal>@SessionScoped</literal> annotation to the method.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
+ <programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
public PaymentStrategy getPaymentStrategy() {
- ...
+ ...
}]]></programlisting>
- <para>Now, when the producer method is called, the returned <literal>PaymentStrategy</literal>
- will be bound to the session context. The producer method won't be called again in the same
- session.</para>
+ <para>
+ Now, when the producer method is called, the returned <literal>PaymentStrategy</literal> will be bound to
+ the session context. The producer method won't be called again in the same session.
+ </para>
-</section>
+ </section>
-<section>
- <title>Injection into producer methods</title>
+ <section>
+ <title>Injection into producer methods</title>
- <para>There's one potential problem with the code above. The implementations of
- <literal>CreditCardPaymentStrategy</literal> are instantiated using the Java
- <literal>new</literal> operator. Objects instantiated directly by the application
- can't take advantage of dependency injection and don't have interceptors.</para>
+ <para>
+ There's one potential problem with the code above. The implementations of
+ <literal>CreditCardPaymentStrategy</literal> are instantiated using the Java <literal>new</literal>
+ operator. Objects instantiated directly by the application can't take advantage of dependency injection and
+ don't have interceptors.
+ </para>
- <para>If this isn't what we want we can use dependency injection into the
- producer method to obtain Web Bean instances:</para>
+ <para>
+ If this isn't what we want we can use dependency injection into the producer method to obtain bean
+ instances:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
+ <programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
public PaymentStrategy getPaymentStrategy(CreditCardPaymentStrategy ccps,
- ChequePaymentStrategy cps,
+ CheckPaymentStrategy cps,
PayPalPaymentStrategy ppps) {
- switch (paymentStrategy) {
- case CREDIT_CARD: return ccps;
- case CHEQUE: return cps;
- case PAYPAL: return ppps;
- default: return null;
- }
+ switch (paymentStrategy) {
+ case CREDIT_CARD: return ccps;
+ case CHEQUE: return cps;
+ case PAYPAL: return ppps;
+ default: return null;
+ }
}]]></programlisting>
- <para>Wait, what if <literal>CreditCardPaymentStrategy</literal> is a request scoped
- Web Bean? Then the producer method has the effect of "promoting" the current request
- scoped instance into session scope. This is almost certainly a bug! The request
- scoped object will be destroyed by the Web Bean manager before the session ends, but
- the reference to the object will be left "hanging" in the session scope. This error
- will <emphasis>not</emphasis> be detected by the Web Bean manager, so please take
- extra care when returning Web Bean instances from producer methods!</para>
+ <para>
+ Wait, what if <literal>CreditCardPaymentStrategy</literal> is a request-scoped bean? Then the producer
+ method has the effect of "promoting" the current request scoped instance into session scope. This is almost
+ certainly a bug! The request scoped object will be destroyed by the container before the session ends, but
+ the reference to the object will be left "hanging" in the session scope. This error will
+ <emphasis>not</emphasis> be detected by the container, so please take extra care when returning bean
+ instances from producer methods!
+ </para>
- <para>There's at least three ways we could go about fixing this bug. We could change
- the scope of the <literal>CreditCardPaymentStrategy</literal> implementation, but this
- would affect other clients of that Web Bean. A better option would be to change the
- scope of the producer method to <literal>@Dependent</literal> or
- <literal>@RequestScoped</literal>.</para>
+ <para>
+ There's at least three ways we could go about fixing this bug. We could change the scope of the
+ <literal>CreditCardPaymentStrategy</literal> implementation, but this would affect other clients of that
+ bean. A better option would be to change the scope of the producer method to <literal>@Dependent</literal>
+ or <literal>@RequestScoped</literal>.
+ </para>
- <para>But a more common solution is to use the special <literal>@New</literal> binding
- annotation.</para>
+ <para>But a more common solution is to use the special <literal>@New</literal> qualifier annotation.</para>
-</section>
+ </section>
-<section>
- <title>Use of <literal>@New</literal> with producer methods</title>
+ <section>
+ <title>Use of <literal>@New</literal> with producer methods</title>
- <para>Consider the following producer method:</para>
+ <para>Consider the following producer method:</para>
-<programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
+ <programlisting role="JAVA"><![CDATA[@Produces @Preferred @SessionScoped
public PaymentStrategy getPaymentStrategy(@New CreditCardPaymentStrategy ccps,
- @New ChequePaymentStrategy cps,
+ @New CheckPaymentStrategy cps,
@New PayPalPaymentStrategy ppps) {
- switch (paymentStrategy) {
- case CREDIT_CARD: return ccps;
- case CHEQUE: return cps;
- case PAYPAL: return ppps;
- default: return null;
- }
+ switch (paymentStrategy) {
+ case CREDIT_CARD: return ccps;
+ case CHEQUE: return cps;
+ case PAYPAL: return ppps;
+ default: return null;
+ }
}]]></programlisting>
- <para>Then a new <emphasis>dependent</emphasis> instance of
- <literal>CreditCardPaymentStrategy</literal> will be created, passed to the producer
- method, returned by the producer method and finally bound to the session context. The
- dependent object won't be destroyed until the <literal>Preferences</literal> object is
- destroyed, at the end of the session.</para>
+ <para>
+ Then a new <emphasis>dependent</emphasis> instance of <literal>CreditCardPaymentStrategy</literal> will be
+ created, passed to the producer method, returned by the producer method and finally bound to the session
+ context. The dependent object won't be destroyed until the <literal>Preferences</literal> object is destroyed,
+ at the end of the session.
+ </para>
-</section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/ri-spi.xml
===================================================================
--- doc/trunk/reference/en-US/ri-spi.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/ri-spi.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,153 +1,120 @@
<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<appendix id="ri-spi">
- <title>Integrating Web Beans into other environments</title>
+ <title>Integrating Weld into other environments</title>
<para>
- If you want to use Web Beans in another environment, you will need to
- provide certain information to Web Beans via the integration SPI. In this
- Appendix we will briefly discuss the steps needed.
+ If you want to use Weld in another environment, you will need to provide certain information to Weld via the
+ integration SPI. In this Appendix we will briefly discuss the steps needed.
</para>
<tip>
<title>Enterprise Services</title>
<para>
- If you just want to use managed beans, and not take advantage of
- enterprise services (EE resource injection, CDI injection into EE
- component classes, transactional events, support for CDI services in
- EJBs) and non-flat deployments, then the generic servlet support
- provided by the "Web Beans: Servlets" extension will be sufficient,
+ If you just want to use managed beans, and not take advantage of enterprise services (EE resource injection,
+ CDI injection into EE component classes, transactional events, support for CDI services in EJBs) and non-flat
+ deployments, then the generic servlet support provided by the "Weld: Servlets" extension will be sufficient,
and will work in any container supporting the Servlet API.
</para>
</tip>
<para>
- All SPIs and APIs described have extensive JavaDoc, which spell out the
- detailed contract between the container and Web Beans.
+ All SPIs and APIs described have extensive JavaDoc, which spell out the detailed contract between the container
+ and Weld.
</para>
<section>
- <title>The Web Beans SPI</title>
+ <title>The Weld SPI</title>
<para>
- The Web Beans SPI is located in the <literal>webbeans-spi</literal>
- module, and packaged as <literal>webbeans-spi.jar</literal>. Some
- SPIs are optional, and should only be implemented if you need to
- override the default behavior; others are required.
+ The Weld SPI is located in the <literal>weld-spi</literal> module, and packaged as
+ <literal>weld-spi.jar</literal>. Some SPIs are optional, and should only be implemented if you need to override
+ the default behavior; others are required.
</para>
<para>
- All interfaces in the SPI support the decorator pattern and provide a
- <literal>Forwarding</literal> class located in the
- <literal>helpers</literal> sub package. Additional, commonly used,
- utility classes, and standard implementations are also located in the
- <literal>helpers</literal> sub package.
+ All interfaces in the SPI support the decorator pattern and provide a <literal>Forwarding</literal> class
+ located in the <literal>helpers</literal> sub package. Additional, commonly used, utility classes, and standard
+ implementations are also located in the <literal>helpers</literal> sub package.
</para>
-
<para>
- Web Beans supports multiple environments. An environment is defined by
- an implementation of the <literal>Environment</literal> interface. A
- number of standard environments are built in, and described by the
- <literal>Environments</literal> enumeration. Different environments
- require different services to be present (for example a Servlet
- container doesn't require transaction, EJB or JPA services). By default
- an EE environment is assumed, but you can adjust the environment by
- calling <literal>bootstrap.setEnvironment()</literal>.
+ Weld supports multiple environments. An environment is defined by an implementation of the
+ <literal>Environment</literal> interface. A number of standard environments are built in, and described by the
+ <literal>Environments</literal> enumeration. Different environments require different services to be present
+ (for example a Servlet container doesn't require transaction, EJB or JPA services). By default an EE
+ environment is assumed, but you can adjust the environment by calling
+ <literal>bootstrap.setEnvironment()</literal>.
</para>
<para>
- Web Beans uses a generic-typed service registry to allow services to be
- registered. All services implement the <literal>Service</literal>
- interface. The service registry allows services to be added and
- retrieved.
+ Weld uses a generic-typed service registry to allow services to be registered. All services implement the
+ <literal>Service</literal> interface. The service registry allows services to be added and retrieved.
</para>
<section>
<title>Deployment structure</title>
<para>
- An application is often comprised of a number of modules. For
- example, a Java EE deployment may contain a number of EJB modules
- (containing business logic) and WAR modules (containing the user
- interface). A container may enforce certain
- <emphasis>accessibility</emphasis> rules which limit the visibility
- of classes between modules. Web Beans allows these same rules to
- apply to bean and observer method resolution. As the accessibility
- rules vary between containers, Web Beans requires the container to
- <emphasis>describe</emphasis> the deployment structure, via the
- <literal>Deployment</literal> SPI.
+ An application is often comprised of a number of modules. For example, a Java EE deployment may contain a
+ number of EJB modules (containing business logic) and WAR modules (containing the user interface). A
+ container may enforce certain <emphasis>accessibility</emphasis> rules which limit the visibility of classes
+ between modules. CDI allows these same rules to apply to bean and observer method resolution. As the
+ accessibility rules vary between containers, Weld requires the container to <emphasis>describe</emphasis>
+ the deployment structure, via the <literal>Deployment</literal> SPI.
</para>
<para>
- The CDI specification discusses
- <emphasis>Bean Deployment Archives</emphasis> (BDAs) — archives which
- are marked as containing beans which should be deployed to the CDI
- container, and made available for injection and resolution. Web
- Beans reuses this description of
- <emphasis>Bean Deployment Archives</emphasis> in its deployment
- structure SPI. Each deployment exposes the BDAs which it contains;
- each BDA may also reference other which it can access. Together, the
- transitive closure of this graph forms the beans which are deployed
- in the application.
+ The CDI specification discusses <emphasis>Bean Deployment Archives</emphasis> (BDAs) — archives which
+ are marked as containing beans which should be deployed to the CDI container, and made available for
+ injection and resolution. Weld reuses this description of <emphasis>Bean Deployment Archives</emphasis> in
+ its deployment structure SPI. Each deployment exposes the BDAs which it contains; each BDA may also
+ reference other which it can access. Together, the transitive closure of this graph forms the beans which
+ are deployed in the application.
</para>
<para>
- To describe the deployment structure to Web Beans, the container
- should provide an implementation of <literal>Deployment</literal>.
- <literal>Deployment.getBeanDeploymentArchives()</literal> allows Web
- Beans to discover the modules which make up the application. The CDI
- specification also allows beans to be specified programmatically as
- part of the bean deployment. These beans may, or may not, be in an
- existing BDA. For this reason, Web Beans will call
- <literal>Deployment.loadBeanDeploymentArchive(Class clazz)</literal>
- for each programmatically described bean.
+ To describe the deployment structure to Weld, the container should provide an implementation of
+ <literal>Deployment</literal>. <literal>Deployment.getBeanDeploymentArchives()</literal> allows Weld to
+ discover the modules which make up the application. The CDI specification also allows beans to be specified
+ programmatically as part of the bean deployment. These beans may, or may not, be in an existing BDA. For
+ this reason, Weld will call <literal>Deployment.loadBeanDeploymentArchive(Class clazz)</literal> for each
+ programmatically described bean.
</para>
<para>
- As programmatically described beans may result in additional BDAs
- being added to the graph, Web Beans will discover the BDA structure
- every time an unknown BDA is returned by
+ As programmatically described beans may result in additional BDAs being added to the graph, Weld will
+ discover the BDA structure every time an unknown BDA is returned by
<literal>Deployment.loadBeanDeploymentArchive</literal>.
</para>
<note>
<title>Virtual BDAs</title>
<para>
- In a strict container, each BDA might have to explicitly specify
- which other BDAs it can access. However many containers will
- allow an easy mechanism to make BDAs bi-directionally accessible
- (such as a library directory). In this case, it is allowable (and
- reasonable) to describe all such archives as a single, 'virtual'
- <literal>BeanDeploymentArchive</literal>.
+ In a strict container, each BDA might have to explicitly specify which other BDAs it can access. However
+ many containers will allow an easy mechanism to make BDAs bi-directionally accessible (such as a library
+ directory). In this case, it is allowable (and reasonable) to describe all such archives as a single,
+ 'virtual' <literal>BeanDeploymentArchive</literal>.
</para>
<para>
- A container, might, for example, use a flat accessibility
- structure for the application. In this case, a single
- <literal>BeanDeploymentArchive</literal> would be attached to the
- <literal>Deployment</literal>.
+ A container, might, for example, use a flat accessibility structure for the application. In this case, a
+ single <literal>BeanDeploymentArchive</literal> would be attached to the <literal>Deployment</literal>.
</para>
</note>
<para>
- <literal>BeanDeploymentArchive</literal> provides three methods
- which allow it's contents to be discovered by Web Beans —
- <literal>BeanDeploymentArchive.getBeanClasses()</literal> must
- return all the classes in the BDA,
- <literal>BeanDeploymentArchive.getBeansXml()</literal> must return
- all the deployment descriptors in the archive, and
- <literal>BeanDeploymentArchive.getEjbs()</literal> must provide an
- EJB descriptor for every EJB in the BDA, or an empty list if it is
- not an EJB archive.
+ <literal>BeanDeploymentArchive</literal> provides three methods which allow it's contents to be discovered
+ by Weld — <literal>BeanDeploymentArchive.getBeanClasses()</literal> must return all the classes in the
+ BDA, <literal>BeanDeploymentArchive.getBeansXml()</literal> must return all the deployment descriptors in
+ the archive, and <literal>BeanDeploymentArchive.getEjbs()</literal> must provide an EJB descriptor for every
+ EJB in the BDA, or an empty list if it is not an EJB archive.
</para>
<para>
- BDA X may also reference another BDA Y whose beans can be resolved
- by, and injected into, any bean in BDA X. These are the accessible
- BDAs, and every BDA that is directly accessible by BDA X should be
- returned. A BDA will also have BDAs which are accessible
- transtivively, and the transitive closure of the sub-graph of BDA X
+ BDA X may also reference another BDA Y whose beans can be resolved by, and injected into, any bean in BDA X.
+ These are the accessible BDAs, and every BDA that is directly accessible by BDA X should be returned. A BDA
+ will also have BDAs which are accessible transtivively, and the transitive closure of the sub-graph of BDA X
describes all the beans resolvable by BDA X.
</para>
@@ -155,34 +122,29 @@
<title>Matching the classloader structure for the deployment</title>
<para>
- In practice, you can regard the deployment structure represented
- by <literal>Deployment</literal>, and the virtual
- BDA graph as a mirror of the classloader structure for a
- deployment. If a class can from BDA X can be loaded by another in
- BDA Y, it is accessible, and therefore BDA Y's accessible BDAs
- should include BDA X.
+ In practice, you can regard the deployment structure represented by <literal>Deployment</literal>, and
+ the virtual BDA graph as a mirror of the classloader structure for a deployment. If a class can from BDA
+ X can be loaded by another in BDA Y, it is accessible, and therefore BDA Y's accessible BDAs should
+ include BDA X.
</para>
</tip>
<para>
- To specify the directly accessible BDAs, the container should
- provide an implementation of
+ To specify the directly accessible BDAs, the container should provide an implementation of
<literal>BeanDeploymentArchive.getBeanDeploymentArchives()</literal>.
</para>
<tip>
<para>
- Web Beans allows the container to describe a circular graph, and
- will convert a graph to a tree as part of the deployment
- process.
+ Weld allows the container to describe a circular graph, and will convert a graph to a tree as part of the
+ deployment process.
</para>
</tip>
<para>
- Certain services are provided for the whole deployment, whilst some
- are provided per-BDA. BDA services are provided using
- <literal>BeanDeploymentArchive.getServices()</literal> and only
- apply to the BDA on which they are provided.
+ Certain services are provided for the whole deployment, whilst some are provided per-BDA. BDA services are
+ provided using <literal>BeanDeploymentArchive.getServices()</literal> and only apply to the BDA on which
+ they are provided.
</para>
</section>
@@ -191,15 +153,13 @@
<title>EJB descriptors</title>
<para>
- Web Beans delegates EJB3 bean discovery to the container so that it
- doesn't duplicate the work done by the EJB container, and respects
- any vendor-extensions to EJB definition,.
+ Weld delegates EJB 3 bean discovery to the container so that it doesn't duplicate the work done by the EJB
+ container, and respects any vendor-extensions to the EJB definition.
</para>
<para>
- The <literal>EjbDescriptor</literal> should return the relevant
- metadata as defined in the EJB specification. Each business
- interface of a session bean should be described using a
+ The <literal>EjbDescriptor</literal> should return the relevant metadata as defined in the EJB
+ specification. Each business interface of a session bean should be described using a
<literal>BusinessInterfaceDescriptor</literal>.
</para>
@@ -209,49 +169,38 @@
<title>EE resource injection and resolution services</title>
<para>
- All the EE resource services are per-BDA services, and may be
- provided using one of two methods. Which method to use is at the
- discretion of the integrator.
+ All the EE resource services are per-BDA services, and may be provided using one of two methods. Which
+ method to use is at the discretion of the integrator.
</para>
<para>
- The integrator may choose to provide all EE resource injection
- services themselves, using another library or framework. In this
- case the integrator should use the <literal>EE</literal>
- environment, and implement the <xref linkend="injection.services" />
- SPI.
+ The integrator may choose to provide all EE resource injection services themselves, using another library or
+ framework. In this case the integrator should use the <literal>EE</literal> environment, and implement the
+ <xref linkend="injection.services" /> SPI.
</para>
<para>
- Alternatively, the integrator may choose to use Web Beans to provide
- EE resource injection. In this case, the
- <literal>EE_INJECT</literal> environment should be used, and the
- integrator should implement the <xref linkend="ejb.services.resolution"/>,
- <xref linkend="resource.services"/> and
- <xref linkend="jpa.services"/>.
+ Alternatively, the integrator may choose to use CDI to provide EE resource injection. In this case, the
+ <literal>EE_INJECT</literal> environment should be used, and the integrator should implement the <xref
+ linkend="ejb.services.resolution"/>, <xref linkend="resource.services"/> and <xref linkend="jpa.services"/>.
</para>
<important>
<para>
- Web Beans only provides annotation-based EE resource injection;
- if you wish to provide deployment descriptor
- (e.g. <literal>ejb-jar.xml</literal>) injection, you must use
- <xref linkend="injection.services"/>.
+ CDI only provides annotation-based EE resource injection; if you wish to provide deployment descriptor
+ (e.g. <literal>ejb-jar.xml</literal>) injection, you must use <xref linkend="injection.services"/>.
</para>
</important>
<para>
- If the container performs EE resource injection, the injected
- resources must be serializable. If EE resource injection is provided
- by Web Beans, the resolved resource must be serializable.
+ If the container performs EE resource injection, the injected resources must be serializable. If EE resource
+ injection is provided by Weld, the resolved resource must be serializable.
</para>
<tip>
<para>
- If you use a non-EE environment then you may implement any of the
- EE service SPIs, and Web Beans will provide the associated
- functionality. There is no need to implement those services you
- don't need!
+ If you use a non-EE environment then you may implement any of the EE service SPIs, and Weld will provide
+ the associated functionality. There is no need to implement those services you don't need!
</para>
</tip>
@@ -261,28 +210,22 @@
<title>EJB services</title>
<para>
- EJB services are split between two interfaces which are both
- per-BDA.
+ EJB services are split between two interfaces which are both per-BDA.
</para>
<para>
- <literal>EJBServices</literal> is used to resolve local EJBs
- used to back session beans, and must always be provided in an EE
- environment.
- <literal>EJBServices.resolveEjb(EjbDescriptor ejbDescriptor)</literal>
- returns a wrapper — <literal>SessionObjectReference</literal> —
- around the EJB reference. This wrapper allows Web Beans to request a
- reference that implements the given business interface, and, in the
- case of SFSBs, both request the removal of the EJB from the container
- and query whether the EJB has been previously removed.
+ <literal>EJBServices</literal> is used to resolve local EJBs used to back session beans, and must always be
+ provided in an EE environment. <literal>EJBServices.resolveEjb(EjbDescriptor ejbDescriptor)</literal>
+ returns a wrapper — <literal>SessionObjectReference</literal> — around the EJB reference. This
+ wrapper allows Weld to request a reference that implements the given business interface, and, in the case of
+ SFSBs, both request the removal of the EJB from the container and query whether the EJB has been previously
+ removed.
</para>
<para id="ejb.services.resolution">
- <literal>EJBResolutionServices.resolveEjb(InjectionPoint ij)</literal>
- allows the resolution of <literal>@EJB</literal> (for injection into
- managed beans). This service is not required if the implementation of
- <xref linkend="injection.services"/> takes care of
- <literal>@EJB</literal> injection.
+ <literal>EJBResolutionServices.resolveEjb(InjectionPoint ij)</literal> allows the resolution of
+ <literal>@EJB</literal> (for injection into managed beans). This service is not required if the
+ implementation of <xref linkend="injection.services"/> takes care of <literal>@EJB</literal> injection.
</para>
</section>
@@ -291,16 +234,14 @@
<title>JPA services</title>
<para>
- Just as EJB resolution is delegated to the container, resolution of
- <literal>@PersistenceContext</literal> for injection into managed
- beans (with the <literal>InjectionPoint</literal> provided), is
- delegated to the container.
+ Just as EJB resolution is delegated to the container, resolution of <literal>@PersistenceContext</literal>
+ for injection into managed beans (with the <literal>InjectionPoint</literal> provided), is delegated to the
+ container.
</para>
<para>
- To allow JPA integration, the <literal>JpaServices</literal>
- interface should be implemented. This service is not required if the
- implementation of <xref linkend="injection.services"/> takes care of
+ To allow JPA integration, the <literal>JpaServices</literal> interface should be implemented. This service
+ is not required if the implementation of <xref linkend="injection.services"/> takes care of
<literal>@PersistenceContext</literal> injection.
</para>
@@ -310,25 +251,20 @@
<title>Transaction Services</title>
<para>
- Web Beans delegates JTA activities to the container. The SPI
- provides a couple hooks to easily achieve this with the
- <literal>TransactionServices</literal> interface.
+ Weld delegates JTA activities to the container. The SPI provides a couple hooks to easily achieve this with
+ the <literal>TransactionServices</literal> interface.
</para>
<para>
- Any <literal>javax.transaction.Synchronization</literal>
- implementation may be passed to the
- <literal>registerSynchronization()</literal> method and the SPI
- implementation should immediately register the synchronization with
- the JTA transaction manager used for the EJBs.
+ Any <literal>javax.transaction.Synchronization</literal> implementation may be passed to the
+ <literal>registerSynchronization()</literal> method and the SPI implementation should immediately register
+ the synchronization with the JTA transaction manager used for the EJBs.
</para>
<para>
- To make it easier to determine whether or not a transaction is
- currently active for the requesting thread, the
- <literal>isTransactionActive()</literal> method can be used. The SPI
- implementation should query the same JTA transaction manager used
- for the EJBs.
+ To make it easier to determine whether or not a transaction is currently active for the requesting thread,
+ the <literal>isTransactionActive()</literal> method can be used. The SPI implementation should query the
+ same JTA transaction manager used for the EJBs.
</para>
</section>
@@ -336,12 +272,10 @@
<title>Resource Services</title>
<para>
- The resolution of <literal>@Resource</literal> (for injection into managed
- beans) is delegated to the container. You must provide an
- implementation of <literal>ResourceServices</literal> which
- provides these operations. This service is not required if the
- implementation of <xref linkend="injection.services"/> takes care of
- <literal>@Resource</literal> injection.
+ The resolution of <literal>@Resource</literal> (for injection into managed beans) is delegated to the
+ container. You must provide an implementation of <literal>ResourceServices</literal> which provides these
+ operations. This service is not required if the implementation of <xref linkend="injection.services"/>
+ takes care of <literal>@Resource</literal> injection.
</para>
</section>
@@ -349,28 +283,22 @@
<title>Injection Services</title>
<para>
- An integrator may wish to use <literal>InjectionServices</literal>
- to provide additional field or method injection over-and-above that
- provided by Web Beans. An integration into a Java EE environment may
- use <literal>InjectionServices</literal> to provide EE resource
- injection for managed beans.
+ An integrator may wish to use <literal>InjectionServices</literal> to provide additional field or method
+ injection over-and-above that provided by Weld. An integration into a Java EE environment may use
+ <literal>InjectionServices</literal> to provide EE resource injection for managed beans.
</para>
<para>
- <literal>InjectionServices</literal> provides a very simple
- contract, the
- <literal>InjectionServices.aroundInject(InjectionContext ic);</literal>
- intercepter will be called for every instance that Web Beans injects,
- whether it is a contextual instance, or a non-contexutal instance
- injected by <literal>InjectionTarget.inject()</literal>.
+ <literal>InjectionServices</literal> provides a very simple contract, the
+ <literal>InjectionServices.aroundInject(InjectionContext ic);</literal> intercepter will be called for every
+ instance that CDI injects, whether it is a contextual instance, or a non-contexutal instance injected by
+ <literal>InjectionTarget.inject()</literal>.
</para>
<para>
- The <literal>InjectionContext</literal> can be used to discover
- additional information about the injection being performed,
- including the <literal>target</literal> being injected.
- <literal>ic.proceed()</literal> should be called to perform
- CDI-style injection, and call initializer methods.
+ The <literal>InjectionContext</literal> can be used to discover additional information about the injection
+ being performed, including the <literal>target</literal> being injected. <literal>ic.proceed()</literal>
+ should be called to perform CDI-style injection, and call initializer methods.
</para>
</section>
@@ -379,32 +307,30 @@
<title>Security Services</title>
<para>
- In order to obtain the <literal>Principal</literal> representing the
- current caller identity, the container should provide an
- implementation of <literal>SecurityServices</literal>.
+ In order to obtain the <literal>Principal</literal> representing the current caller identity, the container
+ should provide an implementation of <literal>SecurityServices</literal>.
</para>
+
</section>
<section>
<title>Bean Validation Services</title>
<para>
- In order to obtain the default <literal>ValidatorFactory</literal>
- for the application deployment, the container should provide an
- implementation of <literal>ValidationServices</literal>.
+ In order to obtain the default <literal>ValidatorFactory</literal> for the application deployment, the
+ container should provide an implementation of <literal>ValidationServices</literal>.
</para>
+
</section>
<section>
<title>Identifying the BDA being addressed</title>
<para>
- When a client makes a request to an application which uses Web
- Beans, the request may be addressed at any of the BDAs in the
- application deployment. To allow the Web Beans to correctly service
- the request, it needs to know which BDA the request is addressed at.
- Where possible, Web Beans will provide some context, but use of
- these by the integrator is optional.
+ When a client makes a request to an application which uses Weld, the request may be addressed at any of the
+ BDAs in the application deployment. To allow Weld to correctly service the request, it needs to know which
+ BDA the request is addressed at. Where possible, Weld will provide some context, but use of these by the
+ integrator is optional.
</para>
<tip>
@@ -415,8 +341,8 @@
</tip>
<para>
- When Web Beans need to identify the BDA, it will use one of these
- services, depending on what is servicing the request:
+ When Weld needs to identify the BDA, it will use one of these services, depending on what is servicing the
+ request:
</para>
<variablelist>
@@ -424,9 +350,7 @@
<term><literal>ServletServices.getBeanDeploymentArchive(ServletContext ctx)</literal></term>
<listitem>
<para>
- Identify the WAR in use. The
- <literal>ServletContext</literal> is provided for
- additional context.
+ Identify the WAR in use. The <literal>ServletContext</literal> is provided for additional context.
</para>
</listitem>
</varlistentry>
@@ -438,11 +362,9 @@
<title>The bean store</title>
<para>
- Web Beans uses a map like structure to store bean instances -
- <literal>org.jboss.webbeans.context.api.BeanStore</literal>. You may
- find
- <literal>org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore</literal>
- useful.
+ Weld uses a map like structure to store bean instances -
+ <literal>org.jboss.weld.context.api.BeanStore</literal>. You may find
+ <literal>org.jboss.weld.context.api.helpers.ConcurrentHashMapBeanStore</literal> useful.
</para>
</section>
@@ -450,10 +372,9 @@
<title>The application context</title>
<para>
- Web Beans expects the Application Server or other container to
- provide the storage for each application's context. The
- <literal>org.jboss.webbeans.context.api.BeanStore</literal> should
- be implemented to provide an application scoped storage.
+ Weld expects the Application Server or other container to provide the storage for each application's
+ context. The <literal>org.jboss.weld.context.api.BeanStore</literal> should be implemented to provide an
+ application scoped storage.
</para>
</section>
@@ -461,59 +382,47 @@
<section>
<title>Initialization and shutdown</title>
<para>
- The <literal>org.jboss.webbeans.bootstrap.api.Bootstrap</literal>
- interface defines the initialization for Web Beans, bean deployment
- and bean validation. To boot Web Beans, you must create an instance
- of
- <literal>org.jboss.webbeans.bootstrap.WebBeansBootstrap</literal>
- (which implements <literal>Boostrap</literal>), tell it about the
- services in use, and then request the container start.
+ The <literal>org.jboss.weld.bootstrap.api.Bootstrap</literal> interface defines the initialization for Weld,
+ bean deployment and bean validation. To boot Weld, you must create an instance of
+ <literal>org.jboss.weld.bootstrap.WeldBeansBootstrap</literal> (which implements
+ <literal>Boostrap</literal>), tell it about the services in use, and then request the container start.
</para>
<para>
- The bootstrap is split into phases, container initialization, bean
- deployment, bean validation and shutdown. Initialization will create
- a manager, and add the built-in contexts, and examine the deployment
- structure. Bean deployment will deploy any beans (defined using
- annotations, programtically, or built in). Bean validation will
- validate all beans.
+ The bootstrap is split into phases, container initialization, bean deployment, bean validation and shutdown.
+ Initialization will create a manager, and add the built-in contexts, and examine the deployment structure.
+ Bean deployment will deploy any beans (defined using annotations, programtically, or built in). Bean
+ validation will validate all beans.
</para>
<para>
- To initialize the container, you call
- <literal>Bootstrap.startInitialization()</literal>. Before calling
- <literal>startInitialization()</literal>, you must register
- any services required by the environment. You can do this by
- calling, for example,
- <literal>bootstrap.getServices().add(JpaServices.class, new MyJpaServices())</literal>.
- You must also provide the application context bean store.
+ To initialize the container, you call <literal>Bootstrap.startInitialization()</literal>. Before calling
+ <literal>startInitialization()</literal>, you must register any services required by the environment. You
+ can do this by calling, for example, <literal>bootstrap.getServices().add(JpaServices.class, new
+ MyJpaServices())</literal>. You must also provide the application context bean store.
</para>
<para>
- Having called <literal>startInitialization()</literal>, the
- <literal>Manager</literal> for each BDA can be obtained by calling
- <literal>Bootstrap.getManager(BeanDeploymentArchive bda)</literal>.
+ Having called <literal>startInitialization()</literal>, the <literal>Manager</literal> for each BDA can be
+ obtained by calling <literal>Bootstrap.getManager(BeanDeploymentArchive bda)</literal>.
</para>
<para>
- To deploy the discovered beans, call
- <literal>Bootstrap.deployBeans()</literal>.
+ To deploy the discovered beans, call <literal>Bootstrap.deployBeans()</literal>.
</para>
<para>
- To validate the deployed beans, call
- <literal>Bootstrap.validateBeans()</literal>.
+ To validate the deployed beans, call <literal>Bootstrap.validateBeans()</literal>.
</para>
<para>
- To place the container into a state where it can service requests,
- call <literal>Bootstrap.endInitialization()</literal>
+ To place the container into a state where it can service requests, call
+ <literal>Bootstrap.endInitialization()</literal>
</para>
<para>
- To shutdown the container you call
- <literal>Bootstrap.shutdown()</literal>. This allows the
- container to perform any cleanup operations needed.
+ To shutdown the container you call <literal>Bootstrap.shutdown()</literal>. This allows the container to
+ perform any cleanup operations needed.
</para>
</section>
@@ -522,12 +431,10 @@
<title>Resource loading</title>
<para>
- Web Beans needs to load classes and resources from the classpath at
- various times. By default, they are loaded from the Thread Context
- ClassLoader if available, if not the same classloader that was used
- to load Web Beans, however this may not be correct for some
- environments. If this is case, you can implement
- <literal>org.jboss.webbeans.spi.ResourceLoader</literal>.
+ Weld needs to load classes and resources from the classpath at various times. By default, they are loaded
+ from the Thread Context ClassLoader if available, if not the same classloader that was used to load Weld,
+ however this may not be correct for some environments. If this is case, you can implement
+ <literal>org.jboss.weld.spi.ResourceLoader</literal>.
</para>
</section>
@@ -538,9 +445,8 @@
<title>The contract with the container</title>
<para>
- There are a number of requirements that the Web Beans RI places on the
- container for correct functioning that fall outside implementation of
- APIs
+ There are a number of requirements that Weld places on the container for correct functioning that fall outside
+ implementation of APIs.
</para>
<variablelist>
@@ -550,10 +456,9 @@
</term>
<listitem>
<para>
- If you are integrating the Web Beans RI into an environment
- that supports deployment of multiple applications, you must
- enable, automatically, or through user configuation,
- classloader isolation for each Web Beans application.
+ If you are integrating Weld into an environment that supports deployment of multiple applications, you
+ must enable, automatically, or through user configuation, classloader isolation for each CDI
+ application.
</para>
</listitem>
</varlistentry>
@@ -563,12 +468,9 @@
</term>
<listitem>
<para>
- If you are integrating the Web Beans into a Servlet
- environment you must register
- <literal>org.jboss.webbeans.servlet.WebBeansListener</literal>
- as a Servlet listener, either automatically, or through user
- configuration, for each Web Beans application which uses
- Servlet.
+ If you are integrating Weld into a Servlet environment you must register
+ <literal>org.jboss.weld.servlet.WeldListener</literal> as a Servlet listener, either
+ automatically, or through user configuration, for each CDI application which uses Servlet.
</para>
</listitem>
</varlistentry>
@@ -579,61 +481,46 @@
<listitem>
<para>
- If you are integrating the Web Beans into a JSF
- environment you must register
- <literal>org.jboss.webbeans.jsf.WebBeansPhaseListener</literal>
- as a phase listener.
+ If you are integrating Weld into a JSF environment you must register
+ <literal>org.jboss.weld.jsf.WeldPhaseListener</literal> as a phase listener.
</para>
<para>
- If you are integrating the Web Beans into a JSF
- environment you must register
- <literal>org.jboss.webbeans.el.WebBeansELContextListener</literal>
- as as an EL Context listener.
+ If you are integrating Weld into a JSF environment you must register
+ <literal>org.jboss.weld.el.WeldELContextListener</literal> as as an EL Context listener.
</para>
<para>
- If you are integrating the Web Beans into a JSF environment
- you must obtain the bean manager for the module and then call
- <literal>BeanManager.wrapExpressionFactory()</literal>,
- passing <literal>Application.getExpressionFactory()</literal>
- as the argument. The wrapped expression factory must be used
- in all EL expression evaluations performed by JSF in this web
- application.
+ If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and
+ then call <literal>BeanManager.wrapExpressionFactory()</literal>, passing
+ <literal>Application.getExpressionFactory()</literal> as the argument. The wrapped expression factory
+ must be used in all EL expression evaluations performed by JSF in this web application.
</para>
<para>
- If you are integrating the Web Beans into a JSF environment
- you must obtain the bean manager for the module and then call
- <literal>BeanManager.getELResolver()</literal>,
- The returned EL resolver should be registered with JSF for
- this web application.
+ If you are integrating Weld into a JSF environment you must obtain the bean manager for the module and
+ then call <literal>BeanManager.getELResolver()</literal>, The returned EL resolver should be
+ registered with JSF for this web application.
</para>
<tip>
<para>
- There are a number of ways you can obtain the bean manager
- for the module. You could call
- <literal>Bootstrap.getManager()</literal>, passing in the
- BDA for this module. Alternatively, you could use the
- injection into Java EE component classes, or look up the
- bean manager in JNDI.
+ There are a number of ways you can obtain the bean manager for the module. You could call
+ <literal>Bootstrap.getManager()</literal>, passing in the BDA for this module. Alternatively, you
+ could use the injection into Java EE component classes, or look up the bean manager in JNDI.
</para>
</tip>
<para>
- If you are integrating the Web Beans into a JSF environment
- you must register
- <literal>org.jboss.webbeans.servlet.ConversationPropagationFilter</literal>
- as a Servlet listener, either automatically, or through user
- configuration, for each Web Beans application which uses
- JSF. This filter can be registered for all Servlet deployment
- safely.
+ If you are integrating Weld into a JSF environment you must register
+ <literal>org.jboss.weld.servlet.ConversationPropagationFilter</literal> as a Servlet listener,
+ either automatically, or through user configuration, for each CDI application which uses JSF.
+ This filter can be registered for all Servlet deployment safely.
</para>
<note>
<para>
- Web Beans only supports JSF 1.2 and above.
+ Weld only supports JSF 1.2 and above.
</para>
</note>
</listitem>
@@ -645,37 +532,28 @@
<listitem>
<para>
- If you are integrating the Web Beans into a JSP
- environment you must register
- <literal>org.jboss.webbeans.el.WebBeansELContextListener</literal>
- as as an EL Context listener.
+ If you are integrating Weld into a JSP environment you must register
+ <literal>org.jboss.weld.el.WeldELContextListener</literal> as as an EL Context listener.
</para>
<para>
- If you are integrating the Web Beans into a JSP environment
- you must obtain the bean manager for the module and then call
- <literal>BeanManager.wrapExpressionFactory()</literal>,
- passing <literal>Application.getExpressionFactory()</literal>
- as the argument. The wrapped expression factory must be used
- in all EL expression evaluations performed by JSP.
+ If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and
+ then call <literal>BeanManager.wrapExpressionFactory()</literal>, passing
+ <literal>Application.getExpressionFactory()</literal> as the argument. The wrapped expression factory
+ must be used in all EL expression evaluations performed by JSP.
</para>
<para>
- If you are integrating the Web Beans into a JSP environment
- you must obtain the bean manager for the module and then call
- <literal>BeanManager.getELResolver()</literal>,
- The returned EL resolver should be registered with JSP for
- this web application.
+ If you are integrating Weld into a JSP environment you must obtain the bean manager for the module and
+ then call <literal>BeanManager.getELResolver()</literal>, The returned EL resolver should be
+ registered with JSP for this web application.
</para>
<tip>
<para>
- There are a number of ways you can obtain the bean manager
- for the module. You could call
- <literal>Bootstrap.getManager()</literal>, passing in the
- BDA for this module. Alternatively, you could use the
- injection into Java EE component classes, or look up the
- bean manager in JNDI.
+ There are a number of ways you can obtain the bean manager for the module. You could call
+ <literal>Bootstrap.getManager()</literal>, passing in the BDA for this module. Alternatively, you
+ could use the injection into Java EE component classes, or look up the bean manager in JNDI.
</para>
</tip>
@@ -687,43 +565,37 @@
</term>
<listitem>
<para>
- If you are integrating the Web Beans into an EJB
- environment you must register
- <literal>org.jboss.webbeans.ejb.SessionBeanInterceptor</literal>
- as a EJB interceptor for all EJBs in the application, either
- automatically, or through user configuration, for each Web
- Beans application which uses enterprise beans.
+ If you are integrating Weld into an EJB environment you must register
+ <literal>org.jboss.weld.ejb.SessionBeanInterceptor</literal> as a EJB interceptor for all EJBs in the
+ application, either automatically, or through user configuration, for each CDI application which
+ uses enterprise beans.
</para>
<important>
<para>
- You must register the <literal>SessionBeanInterceptor</literal>
- as the inner most interceptor in the stack for all EJBs.
+ You must register the <literal>SessionBeanInterceptor</literal> as the inner most interceptor in
+ the stack for all EJBs.
</para>
</important>
</listitem>
</varlistentry>
<varlistentry>
<term>
- The <literal>webbeans-core.jar</literal>
+ The <literal>weld-core.jar</literal>
</term>
<listitem>
<para>
- Web Beans can reside on an isolated classloader, or on a
- shared classloader. If you choose to use an isolated
- classloader, the default <literal>SingletonProvider</literal>,
- <literal>IsolatedStaticSingletonProvider</literal>, can be
- used. If you choose to use a shared classloader, then you will
- need to choose another strategy.
+ Weld can reside on an isolated classloader, or on a shared classloader. If you choose to use an
+ isolated classloader, the default <literal>SingletonProvider</literal>,
+ <literal>IsolatedStaticSingletonProvider</literal>, can be used. If you choose to use a shared
+ classloader, then you will need to choose another strategy.
</para>
<para>
- You can provide your own implementation of
- <literal>Singleton</literal> and
- <literal>SingletonProvider</literal> and register it for use
- using <literal>SingletonProvider.initialize(SingletonProvider provider)</literal>.
+ You can provide your own implementation of <literal>Singleton</literal> and
+ <literal>SingletonProvider</literal> and register it for use using
+ <literal>SingletonProvider.initialize(SingletonProvider provider)</literal>.
</para>
<para>
- Web Beans also provides an implementation of Thread Context
- Classloader per application strategy, via the
+ Weld also provides an implementation of Thread Context Classloader per application strategy, via the
<literal>TCCLSingletonProvider</literal>.
</para>
</listitem>
@@ -734,12 +606,10 @@
</term>
<listitem>
<para>
- You should bind the bean manager for the bean deployment
- archive into JNDI at <literal>java:comp/Manager</literal>. The
- type should be
- <literal>javax.enterprise.inject.spi.BeanManager</literal>. To
- obtain the correct bean manager for the bean deployment
- archive, you may call
+ You should bind the bean manager for the bean deployment archive into JNDI at
+ <literal>java:comp/Manager</literal>. The type should be
+ <literal>javax.enterprise.inject.spi.BeanManager</literal>. To obtain the correct bean manager for the
+ bean deployment archive, you may call
<literal>bootstrap.getBeanManager(beanDeploymentArchive)</literal>
</para>
</listitem>
@@ -750,28 +620,22 @@
</term>
<listitem>
<para>
- The CDI specification requires the container to provide
- injection into non-contextual resources for all Java EE
- component classes. Web Beans delegates this responsibility to
- the container. This can be achieved using the CDI defined
- <literal>InjectionTarget</literal> SPI. Furthermore,
- you must perform this operation on the correct bean manager
- for the bean deployment archive containing the EE component
+ The CDI specification requires the container to provide injection into non-contextual resources for
+ all Java EE component classes. Weld delegates this responsibility to the container. This can be
+ achieved using the CDI defined <literal>InjectionTarget</literal> SPI. Furthermore, you must perform
+ this operation on the correct bean manager for the bean deployment archive containing the EE component
class.
</para>
<para>
- The CDI specification also requires that a
- <literal>ProcessInjectionTarget</literal> event is fired for
- every Java EE component class. Furthermore, if an observer
- calls <literal>ProcessInjectionTarget.setInjectionTarget()</literal>
- the container must use <emphasis>the specified</emphasis> injection
- target to perform injection.
+ The CDI specification also requires that a <literal>ProcessInjectionTarget</literal> event is fired
+ for every Java EE component class. Furthermore, if an observer calls
+ <literal>ProcessInjectionTarget.setInjectionTarget()</literal> the container must use <emphasis>the
+ specified</emphasis> injection target to perform injection.
</para>
<para>
- To help the integrator, Weld provides
- <literal>WeldManager.fireProcessInjectionTarget()</literal>
+ To help the integrator, Weld provides <literal>WeldManager.fireProcessInjectionTarget()</literal>
which returns the <literal>InjectionTarget</literal> to use.
</para>
@@ -798,16 +662,13 @@
it.dispose();
cc.release();]]></programlisting>
<para>
- The container may intersperse other operations between these
- calls. Further, the integrator may choose to implement any of
- these calls in another manner, assuming the contract is
- fulfilled.
+ The container may intersperse other operations between these calls. Further, the integrator may choose
+ to implement any of these calls in another manner, assuming the contract is fulfilled.
</para>
<para>
- When performing injections on EJBs you must use the Web Beans
- defined SPI, <literal>WebBeansManager</literal>. Furthermore,
- you must perform this operation on the correct bean manager
- for the bean deployment archive containing the EJB.
+ When performing injections on EJBs you must use the Weld-defined SPI,
+ <literal>WeldManager</literal>. Furthermore, you must perform this operation on the correct bean
+ manager for the bean deployment archive containing the EJB.
</para>
<programlisting><![CDATA[// Obtain the EjbDescriptor for the EJB
// You may choose to use this utility method to get the descriptor
@@ -825,7 +686,7 @@
// Perform injection and call initializers
it.inject(instance, cc);
-// You may choose to have Web Beans call the post construct and pre destroy
+// You may choose to have CDI call the post construct and pre destroy
// lifecycle callbacks
// Call the post-construct callback
@@ -842,4 +703,7 @@
</variablelist>
</section>
-</appendix>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</appendix>
Modified: doc/trunk/reference/en-US/scopescontexts.xml
===================================================================
--- doc/trunk/reference/en-US/scopescontexts.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/scopescontexts.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,322 +1,365 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="scopescontexts">
- <title>Scopes and contexts</title>
-<para>So far, we've seen a few examples of <emphasis>scope type annotations</emphasis>.
-The scope of a Web Bean determines the lifecycle of instances of the Web Bean. The
-scope also determines which clients refer to which instances of the Web Bean.
-According to the Web Beans specification, a scope determines:</para>
+ <title>Scopes and contexts</title>
-<blockquote>
-<itemizedlist>
- <listitem>
- <para>When a new instance of any Web Bean with that scope is created</para>
- </listitem>
- <listitem>
- <para>When an existing instance of any Web Bean with that scope is destroyed</para>
- </listitem>
- <listitem>
- <para>Which injected references refer to any instance of a Web Bean with that scope</para>
- </listitem>
-</itemizedlist>
-</blockquote>
+ <para>
+ So far, we've seen a few examples of <emphasis>scope type annotations</emphasis>. The scope of a bean determines
+ the lifecycle of instances of the bean. The scope also determines which clients refer to which instances of the
+ bean. According to the CDI specification, a scope determines:
+ </para>
-<para>For example, if we have a session scoped Web Bean, <literal>CurrentUser</literal>,
-all Web Beans that are called in the context of the same <literal>HttpSession</literal>
-will see the same instance of <literal>CurrentUser</literal>. This instance will be
-automatically created the first time a <literal>CurrentUser</literal> is needed in that
-session, and automatically destroyed when the session ends.</para>
+ <blockquote>
+ <itemizedlist>
+ <listitem>
+ <para>When a new instance of any bean with that scope is created</para>
+ </listitem>
+ <listitem>
+ <para>When an existing instance of any bean with that scope is destroyed</para>
+ </listitem>
+ <listitem>
+ <para>Which injected references refer to any instance of a bean with that scope</para>
+ </listitem>
+ </itemizedlist>
+ </blockquote>
-<section>
- <title>Scope types</title>
+ <para>
+ For example, if we have a session-scoped bean, <literal>CurrentUser</literal>, all beans that are called in the
+ context of the same <literal>HttpSession</literal> will see the same instance of <literal>CurrentUser</literal>.
+ This instance will be automatically created the first time a <literal>CurrentUser</literal> is needed in that
+ session, and automatically destroyed when the session ends.
+ </para>
-<para>Web Beans features an <emphasis>extensible context model</emphasis>. It is possible
-to define new scopes by creating a new scope type annotation:</para>
+ <note>
+ <para>
+ There's actually no way to remove a bean from a context explicitly. It turns out that's a good thing because
+ there is no confusion as to which instance you are getting.
+ </para>
+ </note>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <section>
+ <title>Scope types</title>
+
+ <para>
+ CDI features an <emphasis>extensible context model</emphasis>. It's possible to define new scopes by creating
+ a new scope type annotation:
+ </para>
+
+<programlisting role="JAVA"><![CDATA[@ScopeType
+ at Retention(RUNTIME)
@Target({TYPE, METHOD})
- at ScopeType
public @interface ClusterScoped {}]]></programlisting>
-<para>Of course, that's the easy part of the job. For this scope type to be useful, we
-will also need to define a <literal>Context</literal> object that implements the scope!
-Implementing a <literal>Context</literal> is usually a very technical task, intended for
-framework development only.</para>
+ <para>
+ Of course, that's the easy part of the job. For this scope type to be useful, we will also need to define a
+ <literal>Context</literal> object that implements the scope! Implementing a <literal>Context</literal> is
+ usually a very technical task, intended for framework development only. You can expect an implemention of the
+ business scope, for instance, in a future version of Seam.
+ </para>
-<para>We can apply a scope type annotation to a Web Bean implementation class to specify
-the scope of the Web Bean:</para>
+ <para>
+ We can apply a scope type annotation to a bean implementation class to specify the scope of the bean:
+ </para>
-<programlisting role="JAVA"><![CDATA[@ClusterScoped
+ <programlisting role="JAVA"><![CDATA[@ClusterScoped
public class SecondLevelCache { ... }]]></programlisting>
-<!--
+ <para>Usually, you'll use one of CDI's built-in scopes.</para>
-<para>We can even use the scope type to obtain an instance of the <literal>Context</literal>
-object for the scope:</para>
+ </section>
-<programlisting><![CDATA[Bean<SecondLevelCache> cacheBean = manager.resolveByType(SecondLevelCache.class);
-SecondLevelCache cache = manager.getContext(ClusterScoped.class).get(cacheBean);]]></programlisting>
+ <section>
+ <title>Built-in scopes</title>
--->
+ <para>CDI defines four built-in scopes:</para>
-<para>Usually, you'll use one of Web Beans' built-in scopes.</para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>@RequestScoped</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>@SessionScoped</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>@ApplicationScoped</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>@ConversationScoped</literal></para>
+ </listitem>
+ </itemizedlist>
-</section>
+ <para>For a web application that uses CDI:</para>
-<section>
- <title>Built-in scopes</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ any servlet request has access to active request, session and application scopes, and, additionally
+ </para>
+ </listitem>
+ <listitem>
+ <para>any JSF request has access to an active conversation scope.</para>
+ </listitem>
+ </itemizedlist>
-<para>Web Beans defines four built-in scopes:</para>
+ <note>
+ <para>A CDI extension can support the conversation for other frameworks as well.</para>
+ </note>
-<itemizedlist>
- <listitem>
- <para><literal>@RequestScoped</literal></para>
- </listitem>
- <listitem>
- <para><literal>@SessionScoped</literal></para>
- </listitem>
- <listitem>
- <para><literal>@ApplicationScoped</literal></para>
- </listitem>
- <listitem>
- <para><literal>@ConversationScoped</literal></para>
- </listitem>
-</itemizedlist>
+ <para>The request and application scopes are also active:</para>
-<para>For a web application that uses Web Beans:</para>
+ <itemizedlist>
+ <listitem>
+ <para>during invocations of EJB remote methods,</para>
+ </listitem>
+ <listitem>
+ <para>during EJB timeouts,</para>
+ </listitem>
+ <listitem>
+ <para>during message delivery to a message-driven bean, and</para>
+ </listitem>
+ <listitem>
+ <para>during web service invocations.</para>
+ </listitem>
+ </itemizedlist>
-<itemizedlist>
- <listitem>
- <para>any servlet request has access to active request, session and application
- scopes, and, additionally</para>
- </listitem>
- <listitem>
- <para>any JSF request has access to an active conversation scope.</para>
- </listitem>
-</itemizedlist>
+ <para>
+ If the application tries to invoke a bean with a scope that does not have an active context, a
+ <literal>ContextNotActiveException</literal> is thrown by the container at runtime.
+ </para>
-<para>The request and application scopes are also active:</para>
+ <para>
+ Three of the four built-in scopes should be extremely familiar to every Java EE developer, so let's not waste
+ time discussing them here. One of the scopes, however, is new.
+ </para>
-<itemizedlist>
- <listitem>
- <para>during invocations of EJB remote methods,</para>
- </listitem>
- <listitem>
- <para>during EJB timeouts,</para>
- </listitem>
- <listitem>
- <para>during message delivery to a message-driven bean, and</para>
- </listitem>
- <listitem>
- <para>during web service invocations.</para>
- </listitem>
-</itemizedlist>
+ </section>
-<para>If the application tries to invoke a Web Bean with a scope that does not have
-an active context, a <literal>ContextNotActiveException</literal> is thrown by the
-Web Bean manager at runtime.</para>
-
-<para>Three of the four built-in scopes should be extremely familiar to every Java EE
-developer, so let's not waste time discussing them here. One of the scopes, however,
-is new.</para>
-
-</section>
-
-<section>
- <title>The conversation scope</title>
+ <section>
+ <title>The conversation scope</title>
- <para>The Web Beans conversation scope is a bit like the traditional session scope
- in that it holds state associated with a user of the system, and spans multiple
- requests to the server. However, unlike the session scope, the conversation scope:</para>
+ <para>
+ The conversation scope is a bit like the traditional session scope in that it holds state associated with a
+ user of the system, and spans multiple requests to the server. However, unlike the session scope, the
+ conversation scope:
+ </para>
- <itemizedlist>
- <listitem>
- <para>is demarcated explicitly by the application, and</para>
- </listitem>
- <listitem>
- <para>holds state associated with a particular web browser tab in a JSF
- application.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>is demarcated explicitly by the application, and</para>
+ </listitem>
+ <listitem>
+ <para>
+ holds state associated with a particular web browser tab in a JSF application (browsers tend to share
+ domain cookies, and hence the session cookie, between tabs, which is the root of the issue).
+ </para>
+ </listitem>
+ </itemizedlist>
- <para>A conversation represents a task, a unit of work from the point of view
- of the user. The conversation context holds state associated with what the user
- is currently working on. If the user is doing multiple things at the same time,
- there are multiple conversations.</para>
+ <para>
+ A conversation represents a task--a unit of work from the point of view of the user. The conversation context
+ holds state associated with what the user is currently working on. If the user is doing multiple things at the
+ same time, there are multiple conversations.
+ </para>
- <para>The conversation context is active during any JSF request. However, most
- conversations are destroyed at the end of the request. If a conversation should
- hold state across multiple requests, it must be explicitly promoted to a
- <emphasis>long-running conversation</emphasis>.</para>
+ <para>
+ The conversation context is active during any JSF request. Most conversations are destroyed at the end of the
+ request. If a conversation should hold state across multiple requests, it must be explicitly promoted to a
+ <emphasis>long-running conversation</emphasis>.
+ </para>
- <section>
- <title>Conversation demarcation</title>
+ <section>
+ <title>Conversation demarcation</title>
- <para>Web Beans provides a built-in Web Bean for controlling the lifecyle of
- conversations in a JSF application. This Web Bean may be obtained by injection:</para>
+ <para>
+ CDI provides a built-in bean for controlling the lifecyle of conversations in a JSF application. This bean
+ may be obtained by injection:
+ </para>
- <programlisting role="JAVA">@Current Conversation conversation;</programlisting>
+ <programlisting role="JAVA">@Inject Conversation conversation;</programlisting>
- <para>To promote the conversation associated with the current request to a
- long-running conversation, call the <literal>begin()</literal> method from
- application code. To schedule the current long-running conversation context
- for destruction at the end of the current request, call <literal>end()</literal>.</para>
+ <para>
+ To promote the conversation associated with the current request to a long-running conversation, call the
+ <literal>begin()</literal> method from application code. To schedule the current long-running conversation
+ context for destruction at the end of the current request, call <literal>end()</literal>.
+ </para>
- <para>In the following example, a conversation-scoped Web Bean controls the
- conversation with which it is associated:</para>
+ <para>
+ In the following example, a conversation-scoped bean controls the conversation with which it is associated:
+ </para>
-<programlisting role="JAVA">@ConversationScoped @Stateful
+<programlisting role="JAVA"><![CDATA[@ConversationScoped @Stateful
public class OrderBuilder {
+ private Order order;
+ private @Inject Conversation conversation;
+ private @PersistenceContext(type = EXTENDED) EntityManager em;
+
+ @Produces public Order getOrder() {
+ return order;
+ }
- private Order order;
- private @Current Conversation conversation;
- private @PersistenceContext(type=EXTENDED) EntityManager em;
-
- @Produces public Order getOrder() {
- return order;
- }
+ public Order createOrder() {
+ order = new Order();
+ conversation.begin();
+ return order;
+ }
+
+ public void addLineItem(Product product, int quantity) {
+ order.add(new LineItem(product, quantity));
+ }
- public Order createOrder() {
- order = new Order();
- conversation.begin();
- return order;
- }
-
- public void addLineItem(Product product, int quantity) {
- order.add( new LineItem(product, quantity) );
- }
+ public void saveOrder(Order order) {
+ em.persist(order);
+ conversation.end();
+ }
+
+ @Remove
+ public void destroy() {}
+}]]></programlisting>
- public void saveOrder(Order order) {
- em.persist(order);
- conversation.end();
- }
-
- @Remove
- public void destroy() {}
-
-}</programlisting>
-
- <para>This Web Bean is able to control its own lifecycle through use of the
- <literal>Conversation</literal> API. But some other Web Beans have a lifecycle
- which depends completely upon another object.</para>
-
- </section>
+ <para>
+ This bean is able to control its own lifecycle through use of the <literal>Conversation</literal> API. But
+ some other beans have a lifecycle which depends completely upon another object.
+ </para>
+ </section>
- <section>
- <title>Conversation propagation</title>
+ <section>
+ <title>Conversation propagation</title>
- <para>The conversation context automatically propagates with any JSF faces
- request (JSF form submission). It does not automatically propagate with
- non-faces requests, for example, navigation via a link.</para>
+ <para>
+ The conversation context automatically propagates with any JSF faces request (JSF form submission). It does
+ not automatically propagate with non-faces requests, for example, navigation via a link.
+ </para>
- <para>We can force the conversation to propagate with a non-faces request
- by including the unique identifier of the conversation as a request
- parameter. The Web Beans specification reserves the request parameter named
- <literal>cid</literal> for this use. The unique identifier of the conversation
- may be obtained from the <literal>Conversation</literal> object, which has
- the Web Beans name <literal>conversation</literal>.</para>
+ <para>
+ We can force the conversation to propagate with a non-faces request by including the unique identifier of
+ the conversation as a request parameter. The CDI specification reserves the request parameter named
+ <literal>cid</literal> for this use. The unique identifier of the conversation may be obtained from the
+ <literal>Conversation</literal> object, which has the EL bean name <literal>conversation</literal>.
+ </para>
- <para>Therefore, the following link propagates the conversation:</para>
+ <para>
+ Therefore, the following link propagates the conversation:
+ </para>
- <programlisting role="HTML"><![CDATA[<a href="/addProduct.jsp?cid=#{conversation.id}">Add Product</a>]]></programlisting>
-
- <para>The Web Bean manager is also required to propagate conversations
- across any redirect, even if the conversation is not marked long-running.
- This makes it very easy to implement the common POST-then-redirect pattern,
- without resort to fragile constructs such as a "flash" object. In this case,
- the Web Bean manager automatically adds a request parameter to the redirect
- URL.</para>
-
- </section>
+ <programlisting role="HTML"><![CDATA[<a href="/addProduct.jsp?cid=#{conversation.id}">Add Product</a>]]></programlisting>
+
+ <para>
+ Though it's probably better to use one of the link components in JSF 2:
+ </para>
+
+ <programlisting role="HTML"><![CDATA[<h:link outcome="/addProduct.xhtml value="Add Product">
+ <f:param name="cid" value="#{conversation.id}"/>
+</h:link>]]></programlisting>
+
+ <para>
+ The container is also required to propagate conversations across any redirect, even if the conversation is
+ not marked long-running. This makes it very easy to implement the common POST-then-redirect pattern, without
+ resort to fragile constructs such as a "flash" object. In this case, the container automatically adds a
+ request parameter to the redirect URL.
+ </para>
+
+ </section>
- <section>
- <title>Conversation timeout</title>
+ <section>
+ <title>Conversation timeout</title>
- <para>The Web Bean manager is permitted to destroy a conversation and all state
- held in its context at any time in order to preserve resources. A Web Bean
- manager implementation will normally do this on the basis of some kind of
- timeout — though this is not required by the Web Beans specification.
- The timeout is the period of inactivity before the conversation is destroyed.</para>
+ <para>
+ The container is permitted to destroy a conversation and all state held in its context at any time in order
+ to preserve resources. A CDI implementation will normally do this on the basis of some kind of timeout
+ — though this is not required by the CDI specification. The timeout is the period of inactivity before
+ the conversation is destroyed (as opposed to the amount of time the conversation is active).
+ </para>
- <para>The <literal>Conversation</literal> object provides a method to set
- the timeout. This is a hint to the Web Bean manager, which is free to ignore
- the setting.</para>
+ <para>
+ The <literal>Conversation</literal> object provides a method to set the timeout. This is a hint to the
+ container, which is free to ignore the setting.
+ </para>
- <programlisting role="JAVA">conversation.setTimeout(timeoutInMillis);</programlisting>
+ <programlisting role="JAVA">conversation.setTimeout(timeoutInMillis);</programlisting>
- </section>
+ </section>
-</section>
-<section>
- <title>The dependent pseudo-scope</title>
+ </section>
- <para>In addition to the four built-in scopes, Web Beans features the so-called
- <emphasis>dependent pseudo-scope</emphasis>. This is the default scope for a Web Bean
- which does not explicitly declare a scope type.</para>
+ <section>
+ <title>The dependent pseudo-scope</title>
- <para>For example, this Web Bean has the scope type <literal>@Dependent</literal>:</para>
+ <para>
+ In addition to the four built-in scopes, CDI features the so-called <emphasis>dependent
+ pseudo-scope</emphasis>. This is the default scope for a bean which does not explicitly declare a scope type.
+ </para>
-<programlisting role="JAVA"><![CDATA[public class Calculator { ... }]]></programlisting>
+ <para>
+ For example, this bean has the scope type <literal>@Dependent</literal>:
+ </para>
- <para>When an injection point of a Web Bean resolves to a dependent Web Bean,
- a new instance of the dependent Web Bean is created every time the first
- Web Bean is instantiated. Instances of dependent Web Beans are never shared
- between different Web Beans or different injection points. They are
- <emphasis>dependent objects</emphasis> of some other Web Bean instance.</para>
+ <programlisting role="JAVA"><![CDATA[public class Calculator { ... }]]></programlisting>
+
+ <para>
+ When an injection point of a bean resolves to a dependent bean, a new instance of the dependent bean is created
+ when the bean into which it's being injected is instantiated. Instances of dependent beans are never shared
+ between different beans or different injection points. They are strictly <emphasis>dependent objects</emphasis>
+ of some other bean instance.
+ </para>
- <para>Dependent Web Bean instances are destroyed when the instance they
- depend upon is destroyed.</para>
-
- <!--
- <para>Different clients always see different instances of a dependent Web Bean, no
- matter what context they execute in.</para>
- -->
-
- <para>Web Beans makes it easy to obtain a dependent instance of a Java class
- or EJB bean, even if the class or EJB bean is already declared as a Web Bean
- with some other scope type.</para>
+ <para>
+ Dependent bean instances are destroyed when the instance they depend upon is destroyed.
+ </para>
-<section>
- <title>The <literal>@New</literal> annotation</title>
+ <para>
+ CDI makes it easy to obtain a dependent instance of a bean, even if the bean is already declared as a bean with
+ some other scope type.
+ </para>
-<para>The built-in <literal>@New</literal> binding annotation allows
-<emphasis>implicit</emphasis> definition of a dependent Web Bean at an injection point.
-Suppose we declare the following injected field:</para>
+ <section>
+ <title>The <literal>@New</literal> annotation</title>
-<programlisting role="JAVA"><![CDATA[@New Calculator calculator;]]></programlisting>
+ <para>
+ The built-in <literal>@New</literal> qualifier annotation allows <emphasis>implicit</emphasis> definition of
+ a dependent bean at an injection point. Suppose we declare the following injected field:
+ </para>
-<para>Then a Web Bean with scope <literal>@Dependent</literal>, binding type
-<literal>@New</literal>, API type <literal>Calculator</literal>, implementation class
-<literal>Calculator</literal> and deployment type <literal>@Standard</literal> is
-implicitly defined.</para>
+ <programlisting role="JAVA"><![CDATA[@Inject @New Calculator calculator;]]></programlisting>
-<para>This is true even if <literal>Calculator</literal> is <emphasis>already</emphasis>
-declared with a different scope type, for example:</para>
+ <para>
+ Then a bean with scope <literal>@Dependent</literal>, qualifier type <literal>@New</literal>, API type
+ <literal>Calculator</literal>, implementation class <literal>Calculator</literal> and deployment type
+ <literal>@Standard</literal> is implicitly defined.
+ </para>
-<programlisting role="JAVA"><![CDATA[@ConversationScoped
+ <para>
+ This is true even if <literal>Calculator</literal> is <emphasis>already</emphasis> declared with a different
+ scope type, for example:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@ConversationScoped
public class Calculator { ... }]]></programlisting>
-<para>So the following injected attributes each get a different instance of
-<literal>Calculator</literal>:</para>
+ <para>
+ So the following injected attributes each get a different instance of <literal>Calculator</literal>:
+ </para>
-<programlisting role="JAVA"><![CDATA[public class PaymentCalc {
-
- @Current Calculator calculator;
- @New Calculator newCalculator;
-
+ <programlisting role="JAVA"><![CDATA[public class PaymentCalc {
+ @Inject Calculator calculator;
+ @Inject @New Calculator newCalculator;
}]]></programlisting>
-<para>The <literal>calculator</literal> field has a conversation-scoped instance
-of <literal>Calculator</literal> injected. The <literal>newCalculator</literal>
-field has a new instance of <literal>Calculator</literal> injected, with a lifecycle
-that is bound to the owning <literal>PaymentCalc</literal>.</para>
+ <para>
+ The <literal>calculator</literal> field has a conversation-scoped instance of <literal>Calculator</literal>
+ injected. The <literal>newCalculator</literal> field has a new instance of <literal>Calculator</literal>
+ injected, with a lifecycle that is bound to the owning <literal>PaymentCalc</literal>.
+ </para>
-<para>This feature is particularly useful with producer methods, as we'll see in
-the next chapter.</para>
+ <para>
+ This feature is particularly useful with producer methods, as we'll see in the next chapter.
+ </para>
-</section>
+ </section>
-</section>
+ </section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/specialization.xml
===================================================================
--- doc/trunk/reference/en-US/specialization.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/specialization.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,150 +1,221 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="specialization">
-<chapter id="specialization">
- <title>Specialization</title>
+ <title>Specialization, inheritance and alternatives</title>
+
+ <para>
+ When you first start developing with CDI, you'll likely be dealing only with a single bean implementation for each
+ bean type. In this case, it's easy to understand how beans get selected for injection. As the complexity of your
+ application grows, multiple occurances of the same bean type start appearing, either because you have multiple
+ implementations or two beans share a common (Java) inheritance. That's when you have to begin studying the
+ specialization, inheritance and alternative rules to work through unsatisified or ambiguous dependencies or to
+ avoid certain beans from being called.
+ </para>
+
+ <para>
+ The CDI specification recognizes two distinct scenarios in which one bean extends another:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The second bean specializes the first bean in certain deployment scenarios. In these deployments, the second
+ bean completely replaces the first, fulfilling the same role in the system.
+ </para>
+ <para>
+ The second bean is simply reusing the Java implementation, and otherwise bears no relation to the first
+ bean. The first bean may not even have been designed for use as a contextual object.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The second case is the default assumed by CDI. It's possible to have two beans in the system with the same part
+ bean type (interface or parent class). As you've learned, you select between the two implementations using
+ qualifiers.
+ </para>
+
+ <para>
+ The first case is the exception, and also requires more care. In any given deployment, only one bean can fulfill a
+ given role at a time. That means one bean needs to be enabled and the other disabled. There are a two modifiers
+ involved: <literal>@Alternative</literal> and <literal>@Specializes</literal>. We'll start by looking at bean
+ alternatives and then show the guarantees that specialization adds.
+ </para>
+
+ <section>
+ <title>Bean alternatives</title>
+
+ <para>
+ CDI let's you <emphasis>override</emphasis> the implementation of a bean type at deployment time using a bean
+ alternative. For example, the following bean provides an implementation of the
+ <literal>PaymentProcessor</literal> bean type in the default environment:
+ </para>
- <para>We've already seen how the Web Beans dependency injection model lets
- us <emphasis>override</emphasis> the implementation of an API at deployment
- time. For example, the following enterprise Web Bean provides an implementation
- of the API <literal>PaymentProcessor</literal> in production:</para>
-
-<programlisting role="JAVA">@CreditCard @Stateless
+ <programlisting role="JAVA"><![CDATA[@CreditCard
public class CreditCardPaymentProcessor
- implements PaymentProcessor {
- ...
-}</programlisting>
+ implements PaymentProcessor {
+ ...
+}]]></programlisting>
- <para>But in our staging environment, we override that implementation of
- <literal>PaymentProcessor</literal> with a different Web Bean:</para>
+ <para>
+ But in our staging environment, we override that implementation of <literal>PaymentProcessor</literal> with a
+ different bean:
+ </para>
-<programlisting role="JAVA">@CreditCard @Stateless @Staging
+ <programlisting role="JAVA"><![CDATA[@CreditCard @Alternative
public class StagingCreditCardPaymentProcessor
- implements PaymentProcessor {
- ...
-}</programlisting>
+ implements PaymentProcessor {
+ ...
+}]]></programlisting>
- <para>What we've tried to do with <literal>StagingCreditCardPaymentProcessor</literal>
- is to completely replace <literal>AsyncPaymentProcessor</literal> in a particular
- deployment of the system. In that deployment, the deployment type <literal>@Staging</literal>
- would have a higher priority than the default deployment type <literal>@Production</literal>,
- and therefore clients with the following injection point:</para>
-
-<programlisting role="JAVA">@CreditCard PaymentProcessor ccpp</programlisting>
+ <para>or</para>
- <para>Would receive an instance of <literal>StagingCreditCardPaymentProcessor</literal>.</para>
+ <programlisting role="JAVA"><![CDATA[@CreditCard @Alternative
+public class StagingCreditCardPaymentProcessor
+ extends CreditCardPaymentProcessor {
+ ...
+}]]></programlisting>
- <para>Unfortunately, there are several traps we can easily fall into:</para>
-
- <itemizedlist>
- <listitem>
- <para>the higher-priority Web Bean may not implement all the API types of
- the Web Bean that it attempts to override,</para>
- </listitem>
- <listitem>
- <para>the higher-priority Web Bean may not declare all the binding types of
- the Web Bean that it attempts to override,</para>
- </listitem>
- <listitem>
- <para>the higher-priority Web Bean might not have the same name as the Web
- Bean that it attempts to override, or</para>
- </listitem>
- <listitem>
- <para>the Web Bean that it attempts to override might declare a producer
- method, disposal method or observer method.</para>
- </listitem>
- </itemizedlist>
-
- <para>In each of these cases, the Web Bean that we tried to override could still
- be called at runtime. Therefore, overriding is somewhat prone to developer error.</para>
-
- <para>Web Beans provides a special feature, called <emphasis>specialization</emphasis>,
- that helps the developer avoid these traps. Specialization looks a little esoteric
- at first, but it's easy to use in practice, and you'll really appreciate the extra
- security it provides.</para>
-
- <section>
- <title>Using specialization</title>
-
- <para>Specialization is a feature that is specific to simple and enterprise Web Beans.
- To make use of specialization, the higher-priority Web Bean must:</para>
-
- <itemizedlist>
- <listitem>
- <para>be a direct subclass of the Web Bean it overrides, and</para>
- </listitem>
- <listitem>
- <para>be a simple Web Bean if the Web Bean it overrides is a simple Web Bean or
- an enterprise Web Bean if the Web Bean it overrides is an enterprise Web Bean,
- and</para>
- </listitem>
- <listitem>
- <para>be annotated <literal>@Specializes</literal>.</para>
- </listitem>
- </itemizedlist>
-
-<programlisting role="JAVA">@Stateless @Staging @Specializes
+ <para>
+ By default, <literal>@Alternative</literal> beans are disabled. We need to <emphasis>enable</emphasis> the
+ alternative--effectively replacing the bean implementation without the <literal>@Alternative</literal>
+ annotation--in the <literal>beans.xml</literal> descriptor of a bean deployment archive by specifying the bean
+ class (or the class that contains the alternative producer method or field). This activation only applies to
+ beans in the same archive.
+ </para>
+
+ <programlisting role="XML"><![CDATA[<beans
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+ <alternatives>
+ <class>org.mycompany.myapp.StagingCreditCardProcessor</class>
+ </alternatives>
+</beans>]]></programlisting>
+
+ <para>
+ Of course, if the goal is to enable all the alternatives for the staging environment, it would make much more
+ sense to make <literal>@Staging</literal> an <literal>@Alternative</literal> stereotype and annotate the
+ staging beans with this stereotype instead. You'll see how this level of indirection pays off. First, we create
+ the stereotype:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Stereotype
+ at Alternative
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Staging {}]]></programlisting>
+
+ <para>
+ Then we replace the <literal>@Alternative</literal> annotation on our bean with <literal>@Staging</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@CreditCard @Staging
public class StagingCreditCardPaymentProcessor
- extends CreditCardPaymentProcessor {
- ...
-}</programlisting>
+ extends CreditCardPaymentProcessor {
+ ...
+}]]></programlisting>
- <para>We say that the higher-priority Web Bean <emphasis>specializes</emphasis> its
- superclass.</para>
+ <para>
+ Finally, we activate the <literal>@Staging</literal> stereotype in the beans.xml descriptor:
+ </para>
+
+ <programlisting role="XML"><![CDATA[<beans
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://java.sun.com/xml/ns/javaee
+ http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+ <alternatives>
+ <stereotype>org.mycompany.myapp.Staging</stereotype>
+ </alternatives>
+</beans>]]></programlisting>
+
+ <para>
+ Now, no matter how many staging beans we have, they will all be enabled at once. Does that mean the default
+ implementation is disabled? Well, not exactly. If the default implementation has a qualifier, for instance
+ <literal>@LargeTransaction</literal>, and the alternative does not, you could still inject the default
+ implementation.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@LargeTransaction @CreditCard PaymentProcessor paymentProcessor;]]></programlisting>
+
+ <para>
+ So we haven't completely replaced the default implementation in a particular deployment of the system. The only
+ way one bean can completely override a second bean at all injection points is if it implements all the bean
+ types and declares all the qualifiers of the second bean. However, if the second bean declares a producer
+ method or observer method, then even this is not enough to ensure that the second bean is never called! We need
+ something extra.
+ </para>
- </section>
+ <para>
+ CDI provides a special feature, called <emphasis>specialization</emphasis>, that helps the developer avoid
+ these traps. Specialization is a way of informing the system of your intent to completely replace and disable
+ an implementation of a bean.
+ </para>
+ </section>
- <section>
- <title>Advantages of specialization</title>
+ <section>
+ <title>Using specialization</title>
- <para>When specialization is used:</para>
+ <para>
+ When the goal is to replace one bean implementation with a second, to help prevent developer error, the first
+ bean may:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ directly extend the bean class of the second bean, or
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ directly override the producer method, in the case that the second bean is a producer method, and then
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>explicitly declare that it <emphasis>specializes</emphasis> the second bean:</para>
+
+ <programlisting role="JAVA"><![CDATA[@Alternative @Specializes
+public class MockCreditCardPaymentProcessor
+ extends CreditCardPaymentProcessor {
+ ...
+}]]></programlisting>
+
+ <para>
+ When an enabled bean specializes another bean, the other bean is never instantiated or called by the container.
+ Even if the other bean defines a producer or observer method, the method will never be called.
+ </para>
+ </section>
+
+ <section>
+ <title>Inheritance</title>
+
+ <para>
+ So why does specialization work, and what does it have to do with inheritance?
+ </para>
+
+ <para>
+ Since you are informing the container that your alternative bean is meant to stand in as a replacement for the
+ default implementation, the container automatically adds any qualifiers that are on the default implementation
+ to the alternative implementation. Thus, in our example, <literal>MockCreditCardPaymentProcessor</literal> has
+ the qualifiers <literal>@Default</literal> and <literal>@CreditCard</literal>. Therefore, there are no
+ circumstances when the default implementation is going to get used because it is completely shadowed.
+ </para>
+
+ <para>
+ Additionally, if the default implementation declares a bean EL name using <literal>@Named</literal>, the name
+ is inherited by the specialized alternative bean.
+ </para>
+
+ </section>
- <itemizedlist>
- <listitem>
- <para>the binding types of the superclass are automatically inherited by the
- Web Bean annotated <literal>@Specializes</literal>, and</para>
- </listitem>
- <listitem>
- <para>the Web Bean name of the superclass is automatically inherited by the
- Web Bean annotated <literal>@Specializes</literal>, and</para>
- </listitem>
- <listitem>
- <para>producer methods, disposal methods and observer methods declared by the
- superclass are called upon an instance of the Web Bean annotated
- <literal>@Specializes</literal>.</para>
- </listitem>
- </itemizedlist>
-
- <para>In our example, the binding type <literal>@CreditCard</literal> of
- <literal>CreditCardPaymentProcessor</literal> is inherited by
- <literal>StagingCreditCardPaymentProcessor</literal>.</para>
-
- <para>Furthermore, the Web Bean manager will validate that:</para>
-
- <itemizedlist>
- <listitem>
- <para>all API types of the superclass are API types of the Web Bean
- annotated <literal>@Specializes</literal> (all local interfaces
- of the superclass enterprise bean are also local interfaces of the
- subclass),</para>
- </listitem>
- <listitem>
- <para>the deployment type of the Web Bean annotated
- <literal>@Specializes</literal> has a higher precedence than the
- deployment type of the superclass, and</para>
- </listitem>
- <listitem>
- <para>there is no other enabled Web Bean that also specializes
- the superclass.</para>
- </listitem>
- </itemizedlist>
-
- <para>If any of these conditions are violated, the Web Bean manager throws
- an exception at initialization time.</para>
-
- <para>Therefore, we can be certain that the superclass will <emphasis>never</emphasis>
- be called in any deployment of the system where the Web Bean annotated
- <literal>@Specializes</literal> is deployed and enabled.</para>
-
- </section>
-
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/stereotypes.xml
===================================================================
--- doc/trunk/reference/en-US/stereotypes.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/stereotypes.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,179 +1,221 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="stereotypes">
-<chapter id="stereotypes">
- <title>Stereotypes</title>
+ <title>Stereotypes</title>
- <para>According to the Web Beans specification:</para>
+ <para>The CDI specification defines a stereotype as follows:</para>
- <blockquote>
+ <blockquote>
- <para>In many systems, use of architectural patterns produces a set of recurring Web
- Bean roles. A stereotype allows a framework developer to identify such a role and
- declare some common metadata for Web Beans with that role in a central place.</para>
+ <para>
+ In many systems, use of architectural patterns produces a set of recurring bean roles. A stereotype allows a
+ framework de- veloper to identify such a role and declare some common metadata for beans with that role in a
+ central place.
+ </para>
- <para>A stereotype encapsulates any combination of:</para>
+ <para>A stereotype encapsulates any combination of:</para>
- <itemizedlist>
- <listitem>
- <para>a default deployment type,</para>
- </listitem>
- <listitem>
- <para>a default scope type,</para>
- </listitem>
- <listitem>
- <para>a restriction upon the Web Bean scope,</para>
- </listitem>
- <listitem>
- <para>a requirement that the Web Bean implement or extend a certain type, and</para>
- </listitem>
- <listitem>
- <para>a set of interceptor binding annotations.</para>
- </listitem>
- </itemizedlist>
+ <itemizedlist>
+ <listitem>
+ <para>a default scope, and</para>
+ </listitem>
+ <listitem>
+ <para>a set of interceptor bindings.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ A stereotype may also specify that:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>all beans with the stereotype have defaulted bean EL names, or that</para>
+ </listitem>
+ <listitem>
+ <para>all beans with the stereotype are alternatives.</para>
+ </listitem>
+ </itemizedlist>
- <para>A stereotype may also specify that all Web Beans with the stereotype have
- defaulted Web Bean names.</para>
+ <para>
+ A bean may declare zero, one or multiple stereotypes. Stereotype annotations may be applied to a bean class or
+ producer method or field.
+ </para>
- <para>A Web Bean may declare zero, one or multiple stereotypes.</para>
+ </blockquote>
- </blockquote>
+ <para>
+ In layman's terms, a stereotype is a meta-annotation (an annotation used on another annotation) annotated with
+ <literal>@Stereotype</literal> that bundles other Java annotations to give them a particular semantic. For
+ instance, the following stereotype identifies action classes in some MVC framework:
+ </para>
- <para>A stereotype is a Java annotation type. This stereotype identifies
- action classes in some MVC framework:</para>
-
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <programlisting role="JAVA"><![CDATA[@Stereotype
+ at Retention(RUNTIME)
@Target(TYPE)
- at Stereotype
public @interface Action {}]]></programlisting>
- <para>We use the stereotype by applying the annotation to a Web Bean.</para>
+ <para>
+ We use the stereotype by applying the annotation to a bean.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Action
+ <programlisting role="JAVA"><![CDATA[@Action
public class LoginAction { ... }]]></programlisting>
- <section>
- <title>Default scope and deployment type for a stereotype</title>
+ <para>
+ Of course, we need to associate our stereotype annotation with some other annotations or else it isn't doing much
+ for us. Let's see how to add them.
+ </para>
+
+ <section>
+ <title>Default scope for a stereotype</title>
- <para>A stereotype may specify a default scope and/or default deployment
- type for Web Beans with that stereotype. For example, if the deployment
- type <literal>@WebTier</literal> identifies Web Beans that should only
- be deployed when the system executes as a web application, we might
- specify the following defaults for action classes:</para>
+ <para>
+ A stereotype may specify a default scope for beans annotated with the stereotype. For example, if the we might
+ specify the following defaults for action classes in a web application:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- at Target(TYPE)
- at RequestScoped
- at WebTier
+ <programlisting role="JAVA"><![CDATA[@RequestScoped
@Stereotype
-public @interface Action {}]]></programlisting>
-
- <para>Of course, a particular action may still override these defaults
- if necessary:</para>
-
-<programlisting role="JAVA"><![CDATA[@Dependent @Mock @Action
-public class MockLoginAction { ... }]]></programlisting>
-
- <para>If we want to force all actions to a particular scope, we can
- do that too.</para>
-
- </section>
-
- <section>
- <title>Restricting scope and type with a stereotype</title>
-
- <para>Suppose that we wish to prevent actions from declaring certain
- scopes. Web Beans lets us explicitly specify the set of allowed scopes
- for Web Beans with a certain stereotype. For example:</para>
-
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ at Retention(RUNTIME)
@Target(TYPE)
- at RequestScoped
- at WebTier
- at Stereotype(supportedScopes=RequestScoped.class)
public @interface Action {}]]></programlisting>
- <para>If a particular action class attempts to specify a scope other
- than the Web Beans request scope, an exception will be thrown by the
- Web Bean manager at initialization time.</para>
-
- <para>We can also force all Web Bean with a certain stereotype to
- implement an interface or extend a class:</para>
+ <para>
+ Of course, a particular action may still override this default if necessary:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- at Target(TYPE)
- at RequestScoped
- at WebTier
- at Stereotype(requiredTypes=AbstractAction.class)
-public @interface Action {}]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Dependent @Action
+public class DependentScopedLoginAction { ... }]]></programlisting>
- <para>If a particular action class does not extend the class
- <literal>AbstractAction</literal>, an exception will be thrown by the
- Web Bean manager at initialization time.</para>
+ <para>
+ Naturally, overriding a single default isn't much use. But remember, stereotypes can define more than just the
+ default scope.
+ </para>
- </section>
+ </section>
- <section>
- <title>Interceptor bindings for stereotypes</title>
+ <section>
+ <title>Interceptor bindings for stereotypes</title>
- <para>A stereotype may specify a set of interceptor bindings to be
- inherited by all Web Beans with that stereotype.</para>
+ <para>
+ A stereotype may specify a set of interceptor bindings to be inherited by all beans with that stereotype.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- at Target(TYPE)
- at RequestScoped
+<programlisting role="JAVA"><![CDATA[@RequestScoped
@Transactional(requiresNew=true)
@Secure
- at WebTier
@Stereotype
+ at Retention(RUNTIME)
+ at Target(TYPE)
public @interface Action {}]]></programlisting>
- <para>This helps us get technical concerns even further away from the
- business code!</para>
+ <para>
+ This helps us get technical concerns, like transactions and security, even further away from the business code!
+ </para>
- </section>
+ </section>
- <section>
- <title>Name defaulting with stereotypes</title>
+ <section>
+ <title>Name defaulting with stereotypes</title>
- <para>Finally, we can specify that all Web Beans with a certain stereotype
- have a Web Bean name, defaulted by the Web Bean manager. Actions are often
- referenced in JSP pages, so they're a perfect use case for this feature.
- All we need to do is add an empty <literal>@Named</literal> annotation:</para>
+ <para>
+ We can specify that all beans with a certain stereotype have a defaulted EL name when a name is not explicitly
+ defined on that bean. Actions are often referenced in JSF views, so they're a perfect use case for this
+ feature. All we need to do is add an empty <literal>@Named</literal> annotation:
+ </para>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
- at Target(TYPE)
- at RequestScoped
+ <programlisting role="JAVA"><![CDATA[@RequestScoped
@Transactional(requiresNew=true)
@Secure
@Named
- at WebTier
@Stereotype
+ at Retention(RUNTIME)
+ at Target(TYPE)
public @interface Action {}]]></programlisting>
- <para>Now, <literal>LoginAction</literal> will have the name
- <literal>loginAction</literal>.</para>
+ <para>
+ Now, <literal>LoginAction</literal> bean from above will have the name <literal>loginAction</literal>.
+ </para>
- </section>
+ </section>
+
+ <section>
+ <title>Alternatives as stereotypes</title>
+
+ <para>
+ A stereotype can inicate that all beans to which it is applied are <literal>@Alternative</literal> beans. If
+ you can remember back to the early days of the specification, this is the closest match to a deployment type.
+ Whole sets of beans can be enabled or left disabled by activating a single stereotype.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Alternative
+ at Stereotype
+ at Retention(RUNTIME)
+ at Target(TYPE)
+public @interface Mock {}]]></programlisting>
+
+ <para>
+ Now you apply this stereotype to beans that should be active in mock environments.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Mock
+public class MockLoginAction extends LoginAction { ... }]]></programlisting>
+
+ </section>
+
+ <section>
+ <title>Stereotype stacking</title>
+
+ <para>
+ This may blow your mind a bit, but stereotypes may declare other stereotypes, which we'll call
+ <emphasis>stereotype stacking</emphasis>. You may want to do this if you have two distinct
+ stereotypes which are meaningful on their own, but in other situation may be meaningful when
+ combined.
+ </para>
+
+ <para>
+ Here's an example that combines the <literal>@Action</literal> and <literal>@Auditable</literal> stereotypes:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Auditable
+ at Action
+ at Stereotype
+ at Target(TYPE)
+ at Retention(RUNTIME)
+public @interface AuditableAction {}]]></programlisting>
+
+ </section>
- <section>
- <title>Standard stereotypes</title>
+ <section>
+ <title>Built-in stereotypes</title>
- <para>We've already met two standard stereotypes defined by the Web Beans
- specification: <literal>@Interceptor</literal> and <literal>@Decorator</literal>.</para>
+ <para>
+ We've already met two standard stereotypes defined by the CDI specification: <literal>@Interceptor</literal>
+ and <literal>@Decorator</literal>.
+ </para>
- <para>Web Beans defines one further standard stereotype:</para>
+ <para>
+ CDI defines one further standard stereotype, <literal>@Model</literal>, which is expected to be used frequently
+ in web applications:
+ </para>
<programlisting role="JAVA"><![CDATA[@Named
@RequestScoped
@Stereotype
@Target({TYPE, METHOD})
@Retention(RUNTIME)
-public @interface Model {} ]]></programlisting>
+public @interface Model {}]]></programlisting>
- <para>This stereotype is intended for use with JSF. Instead of using JSF
- managed beans, just annotate a Web Bean <literal>@Model</literal>, and
- use it directly in your JSF page.</para>
+ <para>
+ Instead of using JSF managed beans, just annotate a Web Bean <literal>@Model</literal>, and use it directly in
+ your JSF view!
+ </para>
</section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/viewlayers.xml
===================================================================
--- doc/trunk/reference/en-US/viewlayers.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/viewlayers.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,36 +1,44 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="viewlayers">
-<chapter id="viewlayers">
<title>Alternative view layers</title>
<section>
- <title>Using Web Beans with Wicket</title>
+ <title>Wicket CDI integration</title>
+
+ <para>
+ Weld provides integration between the Apache Wicket web framework and CDI. This functionality is provided by
+ the <literal>weld-wicket</literal> extension module, which naturally must be on the classpath of the Wicket
+ application.
+ </para>
+
+ <para>
+ This section describes some of the utilities provided by the Wicket extension module to support the CDI
+ integration.
+ </para>
<section>
<title>The <literal>WebApplication</literal> class</title>
<para>
- Each wicket application must have a
- <literal>WebApplication</literal> subclass; Web Beans provides, for
- your utility, a subclass of this which sets up the Wicket/JSR-299
- integration. You should subclass
- <literal>org.jboss.webbeans.wicket.WebBeansApplication</literal>.
+ Each wicket application must have a <literal>WebApplication</literal> subclass; Weld provides, for your
+ utility, a subclass of this which sets up the Wicket CDI integration. You should subclass
+ <literal>org.jboss.weld.wicket.WeldApplication</literal>.
</para>
<note>
<para>
- If you would prefer not to subclass
- <literal>WebBeansApplication</literal>, you can manually add a
- (small!) number of overrides and listeners to your own
- <literal>WebApplication</literal> subclass. The javadocs of
- <literal>WebBeansApplication</literal>detail this.
+ If you would prefer not to subclass <literal>WeldApplication</literal>, you can manually add a (small!)
+ number of overrides and listeners to your own <literal>WebApplication</literal> subclass. The JavaDocs of
+ <literal>WeldApplication</literal>detail this.
</para>
</note>
<para>
For example:
</para>
- <programlisting><![CDATA[public class SampleApplication extends WebBeansApplication {
+ <programlisting><![CDATA[public class SampleApplication extends WeldApplication {
@Override
public Class getHomePage() {
return HomePage.class;
@@ -41,27 +49,25 @@
<section id="wicketContexts">
<title>Conversations with Wicket</title>
<para>
- The conversation scope can be used in Web Beans with the Apache
- Wicket web framework, through the <literal>webbeans-wicket</literal>
- module. This module takes care of:
+ Wicket can also take advantage of the conversation scope from CDI,
+ provided by the Wicket extension module. This module takes care of:
</para>
<itemizedlist>
<listitem>
<para>
- Setting up the conversation context at the beginning of a
- Wicket request, and tearing it down afterwards
+ Setting up the conversation context at the beginning of a Wicket request, and tearing it down
+ afterwards
</para>
</listitem>
<listitem>
<para>
- Storing the id of any long-running conversation in Wicket's
- metadata when the page response is complete
+ Storing the id of any long-running conversation in Wicket's metadata when the page response is
+ complete
</para>
</listitem>
<listitem>
<para>
- Activating the correct long-running conversation based upon
- which page is being accessed
+ Activating the correct long-running conversation based upon which page is being accessed
</para>
</listitem>
<listitem>
@@ -74,35 +80,35 @@
<section>
<title>Starting and stopping conversations in Wicket</title>
<para>
- As JSF applications, a conversation
- <emphasis>always</emphasis> exists for any request, but its
- lifetime is only that of the current request unless it is
- marked as <emphasis>long-running</emphasis>. For Wicket
- applications this is accomplished as in JSF applications, by
- injecting the <literal>@Current Conversation</literal> and
- then invoking <literal>conversation.begin()</literal>.
- Likewise, conversations are ended with
- <literal>conversation.end()</literal>
+ As in JSF applications, a conversation <emphasis>always</emphasis> exists for any request to Wicket, but its
+ lifetime is only that of the current request unless it is marked as <emphasis>long-running</emphasis>.
+ The boundaries of a long-running conversation are controlled in the same way as in JSF applications,
+ by injecting the <literal>Conversation</literal> instance and invoking either the
+ <literal>begin()</literal>
+ or <literal>end()</literal> methods:
</para>
+
+ <programlisting role="JAVA"><![CDATA[private @Inject Conversation conversation;
+...
+// begin a conversation
+conversation.begin();
+...
+// end a conversation
+conversation.end();]]></programlisting>
+
</section>
<section>
<title>Long running conversation propagation in Wicket</title>
<para>
- When a conversation is marked as long-running, the id of that
- conversation will be stored in Wicket's metadata for the current
- page. If a new page is created and set as the response target
- through <literal>setResponsePage</literal>, this new page will
- also participate in this conversation. This occurs for both
- directly instantiated pages
- (<literal>setResponsePage(new OtherPage())</literal>), as well as
- for bookmarkable pages created with
- <literal>setResponsePage(OtherPage.class)</literal> where
- <literal>OtherPage.class</literal> is mounted as bookmarkable
- from your <literal>WebApplication</literal> subclass (or through
- annotations). In the latter case, because the new page instance
- is not created until after a redirect, the conversation id will
- be propagated through a request parameter, and then stored in
+ When a conversation is marked as long-running, the id of that conversation will be stored in Wicket's
+ metadata for the current page. If a new page is created and set as the response target through
+ <literal>setResponsePage()</literal>, this new page will also participate in this conversation. This
+ occurs for both directly instantiated pages (<literal>setResponsePage(new OtherPage())</literal>), as
+ well as for bookmarkable pages created with <literal>setResponsePage(OtherPage.class)</literal> where
+ <literal>OtherPage.class</literal> is mounted as bookmarkable from your <literal>WebApplication</literal>
+ subclass (or through annotations). In the latter case, because the new page instance is not created until
+ after a redirect, the conversation id will be propagated through a request parameter, and then stored in
page metadata after the redirect.
</para>
</section>
@@ -110,4 +116,7 @@
</section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
Modified: doc/trunk/reference/en-US/xml.xml
===================================================================
--- doc/trunk/reference/en-US/xml.xml 2009-11-02 02:21:34 UTC (rev 4535)
+++ doc/trunk/reference/en-US/xml.xml 2009-11-02 02:51:56 UTC (rev 4536)
@@ -1,188 +1,207 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
-
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
<chapter id="xml">
- <title>Defining Web Beans using XML</title>
- <para>So far, we've seen plenty of examples of Web Beans declared using annotations.
- However, there are a couple of occasions when we can't use annotations to define
- the Web Bean:</para>
+ <title>Defining beans using XML</title>
- <itemizedlist>
- <listitem>
- <para>when the implementation class comes from some preexisting library, or</para>
- </listitem>
- <listitem>
- <para>when there should be multiple Web Beans with the same implementation
- class.</para>
- </listitem>
- </itemizedlist>
+ <para>
+ So far, we've seen plenty of examples of beans declared using annotations. However, there are a couple of
+ occasions when we can't use annotations to define the bean:
+ </para>
- <para>In either of these cases, Web Beans gives us two options:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ when the implementation class comes from some preexisting library, or
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ when there should be multiple beans with the same implementation class.
+ </para>
+ </listitem>
+ </itemizedlist>
- <itemizedlist>
- <listitem><para>write a producer method, or</para></listitem>
- <listitem><para>declare the Web Bean using XML.</para></listitem>
- </itemizedlist>
+ <para>
+ One way to address these problems is to write a producer method. Weld offers another option: declare the bean
+ using XML. This feature will hopefully one day be part of the CDI specification. Until then, it remains a portable
+ extension.
+ </para>
- <para>Many frameworks use XML to provide metadata relating to Java classes. However,
- Web Beans uses a very different approach to specifying the names of Java classes,
- fields or methods to most other frameworks. Instead of writing class and member names
- as the string values of XML elements and attributes, Web Beans lets you use the class
- or member name as the name of the XML element.</para>
+ <para>
+ Many frameworks use XML to provide metadata relating to Java classes. However, Weld uses a very different approach
+ to specifying the names of Java classes, fields or methods to most other frameworks. Instead of writing class and
+ member names as the string values of XML elements and attributes, Weld lets you use the class or member name as
+ the name of the XML element.
+ </para>
- <para>The advantage of this approach is that you can write an XML schema that prevents
- spelling errors in your XML document. It's even possible for a tool to generate the XML
- schema automatically from the compiled Java code. Or, an integrated development environment
- could perform the same validation without the need for the explicit intermediate
- generation step.</para>
+ <para>
+ The advantage of this approach is that you can write an XML schema that prevents spelling errors in your XML
+ document. It's even possible for a tool to generate the XML schema automatically from the compiled Java code. Or,
+ an integrated development environment could perform the same validation without the need for the explicit
+ intermediate generation step.
+ </para>
-<section>
- <title>Declaring Web Bean classes</title>
+ <section>
+ <title>Declaring beans</title>
- <para>For each Java package, Web Beans defines a corresponding XML namespace. The
- namespace is formed by prepending <literal>urn:java:</literal> to the Java package
- name. For the package <literal>com.mydomain.myapp</literal>, the XML namespace is
- <literal>urn:java:com.mydomain.myapp</literal>.</para>
+ <para>
+ For each Java package, Weld defines a corresponding XML namespace. The namespace is formed by prepending
+ <literal>urn:java:</literal> to the Java package name. For the package <literal>com.mydomain.myapp</literal>,
+ the XML namespace is <literal>urn:java:com.mydomain.myapp</literal>.
+ </para>
- <para>Java types belonging to a package are referred to using an XML element in
- the namespace corresponding to the package. The name of the element is the name
- of the Java type. Fields and methods of the type are specified by child elements
- in the same namespace. If the type is an annotation, members are specified by
- attributes of the element.</para>
+ <para>
+ Java types belonging to a package are referred to using an XML element in the namespace corresponding to the
+ package. The name of the element is the name of the Java type. Fields and methods of the type are specified by
+ child elements in the same namespace. If the type is an annotation, members are specified by attributes of the
+ element.
+ </para>
- <para>For example, the element <literal><util:Date/></literal> in the following
- XML fragment refers to the class <literal>java.util.Date</literal>:</para>
+ <para>
+ For example, the element <literal><util:Date/></literal> in the following XML fragment refers to the
+ class <literal>java.util.Date</literal>:
+ </para>
-<programlisting role="XML"><![CDATA[<WebBeans xmlns="urn:java:javax.webbeans"
- xmlns:util="urn:java:java.util">
+ <programlisting role="XML"><![CDATA[<beans xmlns="urn:java:javax.beans"
+ xmlns:util="urn:java:java.util">
+ <util:Date/>
+</beans>]]></programlisting>
- <util:Date/>
+ <para>
+ And this is all the code we need to declare that <literal>Date</literal> is a bean! An instance of
+ <literal>Date</literal> may now be injected by any other bean:
+ </para>
-</WebBeans>]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[private @Inject Date date;]]></programlisting>
- <para>And this is all the code we need to declare that <literal>Date</literal> is
- a simple Web Bean! An instance of <literal>Date</literal> may now be injected by
- any other Web Bean:</para>
+ </section>
-<programlisting role="JAVA"><![CDATA[@Current Date date]]></programlisting>
+ <section>
+ <title>Declaring bean metadata</title>
-</section>
+ <para>
+ We can declare the scope, deployment type and interceptor binding types using direct child elements of the bean
+ declaration:
+ </para>
-<section>
- <title>Declaring Web Bean metadata</title>
-
- <para>We can declare the scope, deployment type and interceptor binding types
- using direct child elements of the Web Bean declaration:</para>
-
-<programlisting role="XML"><![CDATA[<myapp:ShoppingCart>
- <SessionScoped/>
- <myfwk:Transactional requiresNew="true"/>
- <myfwk:Secure/>
+ <programlisting role="XML"><![CDATA[<myapp:ShoppingCart>
+ <SessionScoped/>
+ <myfwk:Transactional requiresNew="true"/>
+ <myfwk:Secure/>
</myapp:ShoppingCart>]]></programlisting>
- <para>We use exactly the same approach to specify names and binding type:</para>
+ <para>We use exactly the same approach to specify names and qualifiers:</para>
-<programlisting role="XML"><![CDATA[<util:Date>
- <Named>currentTime</Named>
+ <programlisting role="XML"><![CDATA[<util:Date>
+ <Named>currentTime</Named>
</util:Date>
<util:Date>
- <SessionScoped/>
- <myapp:Login/>
- <Named>loginTime</Named>
+ <SessionScoped/>
+ <myapp:Login/>
+ <Named>loginTime</Named>
</util:Date>
<util:Date>
- <ApplicationScoped/>
- <myapp:SystemStart/>
- <Named>systemStartTime</Named>
+ <ApplicationScoped/>
+ <myapp:SystemStart/>
+ <Named>systemStartTime</Named>
</util:Date>]]></programlisting>
- <para>Where <literal>@Login</literal> and <literal>@SystemStart</literal> are
- binding annotations types.</para>
+ <para>
+ Where <literal>@Login</literal> and <literal>@SystemStart</literal> are qualifier annotations types.
+ </para>
-<programlisting role="JAVA"><![CDATA[@Current Date currentTime;
- at Login Date loginTime;
- at SystemStart Date systemStartTime;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[private @Inject Date currentTime;
+private @Login Date loginTime;
+private @SystemStart Date systemStartTime;]]></programlisting>
- <para>As usual, a Web Bean may support multiple binding types:</para>
+ <para>As usual, a bean may support multiple qualifier types:</para>
-<programlisting role="XML"><![CDATA[<myapp:AsynchronousChequePaymentProcessor>
- <myapp:PayByCheque/>
- <myapp:Asynchronous/>
+ <programlisting role="XML"><![CDATA[<myapp:AsynchronousChequePaymentProcessor>
+ <myapp:PayByCheque/>
+ <myapp:Asynchronous/>
</myapp:AsynchronousChequePaymentProcessor>]]></programlisting>
- <para>Interceptors and decorators are just simple Web Beans, so they may be
- declared just like any other simple Web Bean:</para>
+ <para>
+ Interceptors and decorators are beans as well, so they may be declared just like any other bean:
+ </para>
-<programlisting role="XML"><![CDATA[<myfwk:TransactionInterceptor>
- <Interceptor/>
- <myfwk:Transactional/>
+ <programlisting role="XML"><![CDATA[<myfwk:TransactionInterceptor>
+ <Interceptor/>
+ <myfwk:Transactional/>
</myfwk:TransactionInterceptor>]]></programlisting>
-</section>
+ </section>
-<section>
- <title>Declaring Web Bean members</title>
+ <section>
+ <title>Declaring bean members</title>
- <para>
- TODO!
- </para>
+ <para>
+ TODO!
+ </para>
-</section>
+ </section>
-<section>
- <title>Declaring inline Web Beans</title>
+ <section>
+ <title>Declaring inline beans</title>
- <para>Web Beans lets us define a Web Bean at an injection point. For example:</para>
+ <para>Weld lets us define a bean at an injection point. For example:</para>
-<programlisting role="XML"><![CDATA[<myapp:System>
- <ApplicationScoped/>
- <myapp:admin>
- <myapp:Name>
- <myapp:firstname>Gavin</myapp:firstname>
- <myapp:lastname>King</myapp:lastname>
- <myapp:email>gavin at hibernate.org</myapp:email>
- </myapp:Name>
- </myapp:admin>
+ <programlisting role="XML"><![CDATA[<myapp:System>
+ <ApplicationScoped/>
+ <myapp:admin>
+ <myapp:Name>
+ <myapp:firstname>Gavin</myapp:firstname>
+ <myapp:lastname>King</myapp:lastname>
+ <myapp:email>gavin at hibernate.org</myapp:email>
+ </myapp:Name>
+ </myapp:admin>
</myapp:System>]]></programlisting>
- <para>The <literal><Name></literal> element declares a simple Web Bean of
- scope <literal>@Dependent</literal> and class <literal>Name</literal>, with a
- set of initial field values. This Web Bean has a special, container-generated
- binding and is therefore injectable only to the specific injection point at
- which it is declared.</para>
+ <para>
+ The <literal><Name></literal> element declares a bean of scope <literal>@Dependent</literal> and class
+ <literal>Name</literal>, with a set of initial field values. This bean has a special, container-generated
+ qualifier and is therefore injectable only to the specific injection point at which it is declared.
+ </para>
- <para>This simple but powerful feature allows the Web Beans XML format to be
- used to specify whole graphs of Java objects. It's not quite a full databinding
- solution, but it's close!</para>
+ <para>
+ This simple but powerful feature allows the Weld XML format to be used to specify whole graphs of Java objects.
+ It's not quite a full databinding solution, but it's close!
+ </para>
-</section>
+ </section>
-<section>
- <title>Using a schema</title>
+ <section>
+ <title>Using a schema</title>
- <para>If we want our XML document format to be authored by people who aren't
- Java developers, or who don't have access to our code, we need to provide
- a schema. There's nothing specific to Web Beans about writing or using the
- schema.</para>
+ <para>
+ If we want our XML document format to be authored by people who aren't Java developers, or who don't have
+ access to our code, we need to provide a schema. There's nothing specific to Weld about writing or using the
+ schema.
+ </para>
-<programlisting role="XML"><![CDATA[<WebBeans xmlns="urn:java:javax.webbeans"
- xmlns:myapp="urn:java:com.mydomain.myapp"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="urn:java:javax.webbeans http://java.sun.com/jee/web-beans-1.0.xsd
- urn:java:com.mydomain.myapp http://mydomain.com/xsd/myapp-1.2.xsd">
+<programlisting role="XML"><![CDATA[<beans xmlns="urn:java:javax.beans"
+ xmlns:myapp="urn:java:com.mydomain.myapp"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="urn:java:javax.beans http://java.sun.com/jee/beans-1.0.xsd
+ urn:java:com.mydomain.myapp http://mydomain.com/xsd/myapp-1.2.xsd">
- <myapp:System>
- ...
- </myapp:System>
+ <myapp:System>
+ ...
+ </myapp:System>
-</WebBeans>]]></programlisting>
+</beans>]]></programlisting>
- <para>Writing an XML schema is quite tedious. Therefore, the Web Beans RI project
- will provide a tool which automatically generates the XML schema from compiled Java
- code.</para>
+ <para>
+ Writing an XML schema is quite tedious. Therefore, the Weld project will provide a tool which automatically
+ generates the XML schema from compiled Java code.
+ </para>
</section>
-</chapter>
\ No newline at end of file
+<!--
+vim:et:ts=3:sw=3:tw=120
+-->
+</chapter>
More information about the weld-commits
mailing list