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>(a)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;
-@OrderProcessor QueueSession orderSession;
+ <programlisting role="JAVA"><![CDATA[@Inject Order order;
+@Inject @OrderMessageProducer MessageProducer producer;
+@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;
-@StockPrices TopicSession priceSession;
+ <!--
+ <programlisting role="JAVA"><![CDATA[@Inject @StockPrices
TopicPublisher pricePublisher;
+@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>(a)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
-@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
+@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
+@Retention(RUNTIME)
@Target({TYPE, METHOD, PARAMETER, FIELD})
-@Documented
-@Qualifier
public @interface LoggedIn {}]]></programlisting>
- <programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+@Retention(RUNTIME)
@Target({METHOD, PARAMETER, FIELD})
-@Documented
-@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
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
-@Documented
-@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
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
-@Documented
-@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
+@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
-@BindingType
-public @interface PayByCheque {}]]></programlisting>
+public @interface Synchronous {}]]></programlisting>
-<programlisting role="JAVA"><![CDATA[@Retention(RUNTIME)
+<programlisting role="JAVA"><![CDATA[@Qualifier
+@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
-@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;
-@PayByCreditCard PaymentProcessor
creditCardPaymentProcessor;]]></programlisting>
+ <programlisting role="JAVA"><![CDATA[@Inject @Synchronous
PaymentProcessor syncPaymentProcessor;
+@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)
-@Target({TYPE, METHOD, FIELD, PARAMETER})
-@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;
-@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>(a)NonBinding</literal>.</para>
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+@Retention(RUNTIME)
+@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
+@Retention(RUNTIME)
+@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
-@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>(a)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>(a)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>(a)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>(a)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
-@Retention(RUNTIME)
-@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;
-@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>(a)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>(a)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
-@InterceptorBindingType
+ <programlisting role="JAVA"><![CDATA[@Transactional @Secure
+@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[(a)Interceptors({TransactionInterceptor.class,
SecurityInterceptor.class})
+ <programlisting
role="JAVA"><![CDATA[(a)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
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
-@Documented
-@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...
+ 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...
+ mailing list and to get involved in <ulink
src="http://seamframework.org/Weld/Development">development&...;.
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>(a)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
+@Retention(RUNTIME)
@Target({TYPE, METHOD})
-@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>(a)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
+@Alternative
+@Retention(RUNTIME)
+@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>(a)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
+@Retention(RUNTIME)
@Target(TYPE)
-@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)
-@Target(TYPE)
-@RequestScoped
-@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)
+@Retention(RUNTIME)
@Target(TYPE)
-@RequestScoped
-@WebTier
-(a)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)
-@Target(TYPE)
-@RequestScoped
-@WebTier
-(a)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)
-@Target(TYPE)
-@RequestScoped
+<programlisting role="JAVA"><![CDATA[@RequestScoped
@Transactional(requiresNew=true)
@Secure
-@WebTier
@Stereotype
+@Retention(RUNTIME)
+@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)
-@Target(TYPE)
-@RequestScoped
+ <programlisting role="JAVA"><![CDATA[@RequestScoped
@Transactional(requiresNew=true)
@Secure
@Named
-@WebTier
@Stereotype
+@Retention(RUNTIME)
+@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
+@Stereotype
+@Retention(RUNTIME)
+@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
+@Action
+@Stereotype
+@Target(TYPE)
+@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>(a)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;
-@Login Date loginTime;
-@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@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@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>