Author: gavin.king(a)jboss.com
Date: 2009-11-10 03:17:29 -0500 (Tue, 10 Nov 2009)
New Revision: 4948
Added:
doc/trunk/reference/en-US/beans.xml
Modified:
doc/trunk/reference/en-US/intro.xml
doc/trunk/reference/en-US/master.xml
doc/trunk/reference/en-US/part2.xml
doc/trunk/reference/en-US/part3.xml
Log:
neverending reorg
Added: doc/trunk/reference/en-US/beans.xml
===================================================================
--- doc/trunk/reference/en-US/beans.xml (rev 0)
+++ doc/trunk/reference/en-US/beans.xml 2009-11-10 08:17:29 UTC (rev 4948)
@@ -0,0 +1,749 @@
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ ]>
+<chapter id="beanscdi">
+ <title>Beans in CDI</title>
+
+ <para>
+ A bean is usually an application class that contains business logic. It may be
called directly from Java code,
+ or it may be invoked via the Unified EL. A bean may access transactional
resources. Dependencies between beans
+ are 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>
+ Let's back up a second. What does it really mean to be
<emphasis>contextual</emphasis>? Since beans may be
+ stateful, it matters <emphasis>which</emphasis> bean instance I
have. Unlike a stateless component model (for
+ example, stateless session beans) or a singleton component model (such as
servlets, or singleton beans),
+ different clients of a bean see the bean in different states. The client-visible
state depends upon which
+ instance of the bean the client has a reference to.
+ </para>
+
+ <para>
+ However, like a stateless or singleton model, but
<emphasis>unlike</emphasis> stateful session beans, the
+ client does not control the lifecycle of the instance by explicitly creating and
destroying it. Instead, the
+ <emphasis>scope</emphasis> of the bean determines:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>the lifecycle of each instance of the bean and</para>
+ </listitem>
+ <listitem>
+ <para>which clients share a reference to a particular instance of the
bean.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ For a given thread in a CDI application, there may be an <emphasis>active
context</emphasis> associated with
+ the scope of the bean. This context may be unique to the thread (for example, if
the bean is request scoped),
+ or it may be shared with certain other threads (for example, if the bean is
session scoped) or even all other
+ threads (if it is application scoped).
+ </para>
+
+ <para>
+ Clients (for example, other beans) executing in the same context will see the
same instance of the bean. But
+ clients in a different context may see a different instance (depending on the
relationship between the
+ contexts).
+ </para>
+
+ <para>
+ One great advantage of the contextual model is that it allows stateful beans to
be treated like services! The
+ client need not concern itself with managing the lifecycle of the bean it's
using, <emphasis>nor does it even
+ need to know what that lifecycle is.</emphasis> Beans interact by passing
messages, and the bean implementations
+ define the lifecycle of their own state. The beans are loosely coupled because:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>they interact via well-defined public APIs</para>
+ </listitem>
+ <listitem>
+ <para>their lifecycles are completely decoupled</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ We can replace one bean with another different bean that implements the same
interface and has a different lifecycle
+ (a different scope) without affecting the other bean implementation. In fact,
CDI defines a simple facility for
+ overriding bean implementations at deployment time, as we will see in <xref
linkend="alternatives"/>.
+ </para>
+
+ <para>
+ Note that not all clients of a bean are beans themselves. Other objects such as
servlets or message-driven
+ beans—which are by nature not injectable, contextual
objects—may also obtain references to beans by
+ injection.
+ </para>
+
+ <section id="bean-anatomy">
+ <title>The anatomy of a bean</title>
+
+ <para>Enough hand-waving. More formally, the anatomy of a bean, according to
the spec:</para>
+
+ <blockquote>
+
+ <para>A bean comprises the following attributes:</para>
+
+ <itemizedlist>
+ <listitem><para>A (nonempty) set of bean
types</para></listitem>
+ <listitem><para>A (nonempty) set of
qualifiers</para></listitem>
+ <listitem><para>A scope</para></listitem>
+ <listitem><para>Optionally, a bean EL
name</para></listitem>
+ <listitem><para>A set of interceptor
bindings</para></listitem>
+ <listitem><para>A bean
implementation</para></listitem>
+ </itemizedlist>
+
+ <para>Furthermore, a bean may or may not be an alternative.</para>
+
+ </blockquote>
+
+ <para>Let's see what all this new terminology means.</para>
+
+ <section>
+ <title>Bean types, qualifiers and dependency injection</title>
+
+ <para>
+ Beans usually acquire references to other beans via dependency injection. Any
injected attribute specifies a
+ "contract" that must be satisfied by the bean to be injected. The
contract is:
+ </para>
+
+ <itemizedlist>
+ <listitem><para>a bean type, together
with</para></listitem>
+ <listitem><para>a set of
qualifiers.</para></listitem>
+ </itemizedlist>
+
+ <para>
+ A bean type is a user-defined class or interface; a type that is
client-visible. If the bean is an EJB
+ session bean, the bean type is the <literal>@Local</literal>
interface or bean-class local view. A bean may
+ have multiple bean types. For example, the following bean has four bean
types:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class BookShop
+ extends Business
+ implements Shop<Book> {
+ ...
+}]]></programlisting>
+
+ <para>
+ The bean types are <literal>BookShop</literal>,
<literal>Business</literal> and
+ <literal>Shop<Book></literal>, as well as the
implicit type <literal>java.lang.Object</literal>.
+ (Notice that a parameterized type is a legal bean type).
+ </para>
+
+ <para>
+ Meanwhile, this session bean has only the local interfaces
<literal>BookShop</literal>,
+ <literal>Auditable</literal> and
<literal>java.lang.Object</literal> as bean types, since the bean class,
+ <literal>BookShopBean</literal> is not a client-visible type.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Stateful
+public class BookShopBean
+ extends Business
+ implements BookShop, Auditable {
+ ...
+}]]></programlisting>
+
+ <note>
+ <para>
+ Most bean types you can probably figure out. One gotcha is primitive
types. All primitive types are assumed
+ to be identical to their corresponding wrapper types in
<literal>java.lang</literal>.
+ </para>
+ </note>
+
+ <para>
+ Bean types may be restricted to an explicit set by annotating the bean with
the <literal>@Typed</literal>
+ annotation and listing the classes that should be bean types. For instance,
the bean types of this bean have
+ been restricted to <literal>Shop<Book></literal>,
together with <literal>java.lang.Object</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[(a)Typed(Shop.class)
+public class BookShop
+ extends Business
+ implements Shop<Book> {
+ ...
+}]]></programlisting>
+
+ <para>
+ Sometimes, a bean type alone does not provide enough information for the
container to know which bean to inject.
+ For instance, suppose we have two implementations of the
<literal>PaymentProcessor</literal> interface:
+ <literal>CreditCardPaymentProcessor</literal> and
<literal>DebitPaymentProcessor</literal>. Injecting a field of
+ type <literal>PaymentProcessor</literal> introduces an ambiguous
condition. In these cases, the client must
+ specify some additional quality of the implementation it is interested in. We
model this kind of "quality" using
+ a qualifier.
+ </para>
+
+ <para>
+ A qualifier is a user-defined annotation that is itself annotated
<literal>@Qualifer</literal>. A qualifier
+ annotation is an extension of the type system. It lets us disambiguate a type
without having to fall back to
+ string-based names. Here's an example of a qualifier annotation:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Qualifier
+@Target({TYPE, METHOD, PARAMETER, FIELD})
+@Retention(RUNTIME)
+public @interface CreditCard {}]]></programlisting>
+
+ <para>
+ You may not be used to seeing the definition of an annotation. In fact, this
might be the first time you've
+ encountered one. With CDI, annotation definitions will become a familiar
artifact as you'll be creating them
+ from time to time.
+ </para>
+
+ <tip>
+ <para>
+ Pay attention to the names of the built-in annotations in CDI and EJB.
You'll notice that they are
+ often adjectives. We encourage you to follow this convention when creating
your custom annotations,
+ since they serve to describe the behaviors and roles of the class.
+ </para>
+ </tip>
+
+ <para>
+ Now that we have defined a qualifier annotation, we can use it to
disambiguate an injection point. The
+ following injection point has the bean type
<literal>PaymentProcessor</literal> and qualifier
+ <literal>@CreditCard</literal>:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Inject @CreditCard
PaymentProcessor paymentProcessor]]></programlisting>
+
+ <note>
+ <para>
+ If an injection point does not explicitly specify a qualifier, it has the
default qualifier,
+ <literal>@Default</literal>.
+ </para>
+ </note>
+
+ <para>
+ For each injection point, the container searches for a bean which satisfies
the contract, one which has
+ the bean type and all the qualifiers. If it finds exactly one matching bean,
it injects an instance of
+ that bean. If it doesn't, it reports an error to the user.
+ </para>
+
+ <para>
+ How do we specify that qualifiers of a bean? By annotating the bean class, of
course! The following bean
+ has the qualifier <literal>@CreditCard</literal> and implements
the bean type <literal>PaymentProcessor</literal>.
+ Therefore, it satisfies our qualified injection point:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@CreditCard
+public class CreditCardPaymentProcessor
+ implements PaymentProcessor { ... }]]></programlisting>
+
+ <note>
+ <para>
+ If a bean does not explicitly specify a qualifier, it has the default
qualifier, <literal>@Default</literal>.
+ </para>
+ </note>
+
+ <!--
+ <note>
+ <para>
+ All beans have the qualifier, <literal>@Any</literal>.
+ </para>
+ </note>
+ -->
+
+ <para>
+ That's not quite the end of the story. CDI also defines a simple
<emphasis>resolution rule</emphasis> that helps
+ the container decide what to do if there is more than one bean that satisfies
a particular contract. We'll get
+ into the details in <xref linkend="injection"/>.
+ </para>
+
+ <!--
+ <tip>
+ <para>
+ If you're expectng more than one bean to satisfy the contract, you can
inject an <literal>Instance</literal>,
+ object which let's you iterate over all the beans which satisfy the
contract. For example, we can iterate
+ over all our implementations of
<literal>PaymentProcessor</literal> using:
+ </para>
+ <programlisting>@Inject void init(@Any
Instance<PaymentProcessor> paymentProcessorInstance) {
+ for (PaymentProcessor pp: paymentProcessorInstance) { ... }
+}</programlisting>
+ </tip>
+ -->
+
+ </section>
+
+ <section>
+ <title>Scope</title>
+ <!-- I wonder whether the explaination of contextual above would fit better
here -->
+
+ <para>
+ The <emphasis>scope</emphasis> of a bean defines the lifecycle
and visibility of its instances.
+ The CDI context model is extensible, accommodating arbitrary scopes. However,
certain important scopes are
+ built into the specification, and provided by the container. Each scope is
represented by an annotation
+ type.
+ </para>
+
+ <para>
+ For example, any web application may have <emphasis>session
scoped</emphasis> bean:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @SessionScoped
+class ShoppingCart implements Serializable { ... }]]></programlisting>
+
+ <para>An instance of a session-scoped bean is bound to a user session
+ and is shared by all requests that execute in the context of that
session.</para>
+
+ <note>
+ <para>
+ Keep in mind that once a bean is bound to a context, it remains in that
context until the context is
+ destroyed. There is no way to explicitly remove a bean from a context. If
you don't the bean to live in
+ the session indefinitely, consider using another scope such as the request
or conversation scope instead.
+ </para>
+ </note>
+
+ <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 object into which they
+ were 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>
+
+ </section>
+
+ <section>
+ <title>EL name</title>
+
+ <para>
+ If you want to reference a bean in non-Java code that supports Unified EL
expressions, for example, in a
+ JSP or JSF page, you must assign the bean an <emphasis>EL
name</emphasis>.
+ </para>
+
+ <para>
+ The EL name is specified using the <literal>@Named</literal>
annotation, as shown here:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Named("cart")
+class ShoppingCart implements Serializable { ... }]]></programlisting>
+
+ <para>Now we can easily use the bean in any JSF or JSP page:</para>
+
+ <programlisting role="XML"><![CDATA[<h:dataTable
value="#{cart.lineItems}" var="item">
+ ...
+</h:dataTable>]]></programlisting>
+
+ <note>
+ <para>
+ The <literal>@Named</literal> annotation is not what makes the
class a bean. Most classes in a bean
+ archive are already recognized as beans. The
<literal>@Named</literal> annotation just makes it
+ possible to reference the bean from the EL, most commonly from a JSF
view.
+ </para>
+ </note>
+
+ <para>
+ We can let CDI choose a name for us by leaving off the value of the
<literal>@Named</literal> annotation:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Named
+class ShoppingCart implements Serializable { ... }]]></programlisting>
+
+ <para>
+ The name defaults to the unqualified class name, decapitalized; in this
case,
+ <literal>shoppingCart</literal>.
+ </para>
+
+ </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>
+
+ <para>
+ We've already seen how qualifiers let us choose between multiple
implementations of an interface
+ at development time. But sometimes we have an interface (or other bean type)
whose implementation
+ varies depending upon the deployment environment. For example, we may want to
use a mock
+ implementation in a testing environment. An
<emphasis>alternative</emphasis> may be declared by
+ annotating the bean class with the
<literal>@Alternative</literal> annotation.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @Alternative
+class MockPaymentProcessor extends PaymentProcessorImpl { ...
}]]></programlisting>
+
+ <para>
+ We normally annotate a bean <literal>@Alternative</literal> only
when there is some other
+ implementation of an interface it implements (or of any of its bean types).
We can choose between
+ alternatives at deployment time by <emphasis>selecting</emphasis>
an alternative in the CDI
+ deployment descriptor <literal>META-INF/beans.xml</literal> of
the jar or Java EE module that uses
+ it. Different modules can specify that they use different alternatives.
+ </para>
+
+ <para>
+ We cover alternatives in more detail in <xref
linkend="alternatives"/>.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Interceptor binding types</title>
+
+ <para>
+ You might be familiar with the use of interceptors in EJB 3.0. In Java EE 6,
this functionality has
+ been generalized to work with other managed beans. That's right, you no
longer have to make your bean
+ an EJB just to intercept its methods. Holler. So what does CDI have to offer
above and beyond that? Well,
+ quite a lot actually. Let's cover some background.
+ </para>
+
+ <para>
+ The way that interceptors were defined in Java EE 5 was counter-intuitive.
You were required to specify the
+ <emphasis>implementation</emphasis> of the interceptor directly
on the <emphasis>implementation</emphasis>
+ of the EJB, either in the <literal>@Interceptors</literal>
annotation or in the XML descriptor. You might as
+ well just put the interceptor code <emphasis>in</emphasis> the
implementation! Second, the order in which
+ the interceptors are applied is taken from the order in which they are
declared in the annotation or the XML
+ descriptor. Perhaps this isn't so bad if you're applying the
interceptors to a single bean. But, if you are
+ applying them repeatedly, then there's a good chance that you'll
inadvertently define a different order for
+ different beans. Now that's a problem.
+ </para>
+
+ <para>
+ CDI provides a new approach to binding interceptors to beans that introduces
a level of indirection (and
+ thus control). We must define an <emphasis>interceptor binding
type</emphasis> to describe the behavior
+ implemented by the interceptor.
+ </para>
+
+ <para>
+ An interceptor binding type is a user-defined annotation that is itself
annotated <literal>@InterceptorBinding</literal>.
+ It lets us bind interceptor classes to bean classes with no direct dependency
between the two classes.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@InterceptorBinding
+@Inherited
+@Target( { TYPE, METHOD })
+@Retention(RUNTIME)
+public @interface Transactional {}]]></programlisting>
+
+ <para>
+ The interceptor that implements transaction management declares this
annotation:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @Transactional
@Interceptor
+class TransactionInterceptor { ... }]]></programlisting>
+
+ <para>
+ We can apply the interceptor to a bean by annotating the bean class with the
same interceptor binding type:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Transactional
+class ShoppingCart implements Serializable { ... }]]></programlisting>
+
+ <para>
+ Notice that <literal>ShoppingCart</literal> and
<literal>TransactionInterceptor</literal> don't know
+ anything about each other.
+ </para>
+
+ <para>
+ Interceptors are deployment-specific. (We don't need a
<literal>TransactionInterceptor</literal> in our
+ unit tests!) By default, an interceptor is disabled. We can enable an
interceptor using the CDI deployment
+ descriptor <literal>META-INF/beans.xml</literal> of the jar or
Java EE module. This is also where we
+ specify the interceptor ordering.
+ </para>
+
+ <para>
+ We'll discuss interceptors, and their cousins, decorators, in <xref
linkend="interceptors"/> and <xref
+ linkend="decorators"/>.
+ </para>
+
+ </section>
+
+ </section>
+
+ <section>
+ <title>What kinds of classes are beans?</title>
+
+ <para>
+ We've already seen two types of beans: JavaBeans and EJB session beans. Is
that the whole story? Actually,
+ it's just the beginning. Let's explore the various kinds of beans that
CDI implementations must support
+ out-of-the-box.
+ </para>
+
+ <section>
+ <title>Managed beans</title>
+
+ <para>
+ A managed bean is a Java class. The basic lifecycle and semantics of a
managed bean are defined by the
+ Managed Beans specification. You can explicitly declare a managed bean by
annotating the bean class
+ <literal>@ManagedBean</literal>, but in CDI you don't need
to. According to the specification, the CDI
+ container treats any class that satisfies the following conditions as a
managed bean:
+ </para>
+
+ <blockquote>
+
+ <itemizedlist>
+ <listitem>
+ <para>It is not a non-static inner class.</para>
+ </listitem>
+ <listitem>
+ <para>It is a concrete class, or is annotated
<literal>(a)Decorator</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>
+ It is not annotated with an EJB component-defining annotation or
declared as an EJB bean class in
+ <literal>ejb-jar.xml</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>It does not implement
<literal>javax.enterprise.inject.spi.Extension</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>
+ It has an appropriate constructor—either:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>the class has a constructor with no parameters,
or</para>
+ </listitem>
+ <listitem>
+ <para>the class declares a constructor annotated
<literal>(a)Inject</literal>.</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+
+ </blockquote>
+
+ <para>The unrestricted set of bean types for a managed bean contains the
bean class, every superclass and all
+ interfaces it implements directly or indirectly.</para>
+
+ <para>If a managed bean has a public field, it must have the default scope
<literal>(a)Dependent</literal>.</para>
+
+ <para>Managed beans support the
<literal>@PostConstruct</literal> and
<literal>@PreDestroy</literal> lifecycle
+ callbacks.</para>
+
+ <para>
+ Session beans are also, technically, managed beans. However, since they have
their own special lifecycle and
+ take advantage of additional enterprise services, the CDI specification
considers them to be a different
+ kind of bean.
+ </para>
+
+ </section>
+
+ <section>
+ <title>Session beans</title>
+
+ <para>
+ Session beans belong to the EJB specification. They have a special lifecycle,
state management and concurrency
+ model that is different to other managed beans and non-managed Java objects.
But session beans participate in
+ CDI just like any other bean. You can inject one session bean into another
session bean, a managed bean into a
+ session bean, a session bean into a managed bean, have a managed bean observe
an event raised by a session bean,
+ and so on.
+ </para>
+
+ <note>
+ <para>
+ Message-driven and entity beans are by nature non-contextual objects and
may not be injected into other
+ objects. However, message-driven beans can take advantage of some CDI
functionality, such as dependency
+ injection, interceptors and decorators. In fact, CDI will perform
injection into any session or
+ message-driven bean, even those which are not contextual instances.
+ </para>
+ </note>
+
+ <para>
+ The unrestricted set of bean types for a session bean contains all local
interfaces of the bean and their
+ superinterfaces. If the session bean has a bean class local view, the
unrestricted set of bean types
+ contains the bean class and all superclasses. In addition,
<literal>java.lang.Object</literal> is a bean
+ type of every session bean. But remote interfaces are
<emphasis>not</emphasis> included in the set of bean
+ types.
+ </para>
+
+ <para>There's no reason to explicitly declare the scope of a stateless
session bean or singleton session bean.
+ The EJB container controls the lifecycle of these beans, according to the
semantics of the <literal>@Stateless</literal>
+ or <literal>@Singleton</literal> declaration. On the other hand, a
stateful session bean may have any scope.</para>
+
+ <para>
+ Stateful session beans may define a <emphasis>remove
method</emphasis>, annotated <literal>@Remove</literal>,
+ that is used by the application to indicate that an instance should be
destroyed. However, for a contextual
+ instance of the bean—an instance under the control of
CDI—this method may only be called by the
+ application if the bean has scope <literal>@Dependent</literal>.
For beans with other scopes, the application
+ must let the container destroy the bean.
+ </para>
+
+ <para>
+ So, when should we use a session bean instead of a plain managed bean?
Whenever we need the advanced enterprise
+ services offered by EJB, such as:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>method-level transaction management and security,</para>
+ </listitem>
+ <listitem>
+ <para>concurrency management,</para>
+ </listitem>
+ <listitem>
+ <para>instance-level passivation for stateful session beans and
+ instance-pooling for stateless session beans,</para>
+ </listitem>
+ <listitem>
+ <para>remote or web service invocation, or</para>
+ </listitem>
+ <listitem>
+ <para>timers and asynchronous methods,</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>When we don't need any of these things, an ordinary managed bean
will serve just fine.</para>
+
+ <para>
+ Many beans (including any <literal>@SessionScoped</literal> or
<literal>@ApplicationScoped</literal>
+ beans) are available for concurrent access. Therefore, the concurrency
management provided by EJB 3.1
+ is especially useful. Most session and application scoped beans should be
EJBs.
+ </para>
+
+ <para>
+ Beans which hold references to heavy-weight resources, or hold a lot of
internal state benefit from the
+ advanced container-managed lifecycle defined by the EJB
stateless/stateful/singleton model, with its
+ support for passivation and instance pooling.
+ </para>
+
+ <para>
+ Finally, it's usually obvious when method-level transaction management,
method-level security, timers,
+ remote methods or asynchronous methods are needed.
+ </para>
+
+ <para>
+ The point we're trying to make is: use a session bean when you need the
services it provides, not just
+ because you want to use dependency injection, lifecycle management, or
interceptors. Java EE 6 provides
+ a graduated programming model. It's usually easy to start with an
ordinary managed bean, and later turn
+ it into an EJB just by adding one of the following annotations:
<literal>@Stateless</literal>,
+ <literal>@Stateful</literal> or
<literal>@Singleton</literal>.
+ </para>
+
+ <para>
+ On the other hand, don't be scared to use session beans just because
you've heard your friends say
+ they're "heavyweight". It's nothing more than superstition
to think that something is "heavier" just
+ because it's hosted natively within the Java EE container, instead of by
a proprietary bean container
+ or dependency injection framework that runs as an additional layer of
obfuscation. And as a general
+ principle, you should be skeptical of folks who use vaguely defined
terminology like "heavyweight".
+ </para>
+
+ </section>
+
+ <section>
+ <title>Producer methods</title>
+
+ <para>
+ Not everything that needs to be injected can be boiled down to a bean class
instantiated by the container
+ using <literal>new</literal>. There are plenty of cases where we
need additional control. What if we need
+ to decide at runtime which implementation of a type to instantiate and
inject? What if we need to inject
+ an object that is obtained by querying a service or transactional resource,
for example by executing a JPA
+ query?
+ </para>
+
+ <para>
+ A <emphasis>producer method</emphasis> is a method that acts as a
source of bean instances. The method
+ declaration itself describes the bean and the container invokes the method to
obtain an instance of the
+ bean when no instance exists in the specified context. A producer method lets
the application take full
+ control of the bean instantiation process.
+ </para>
+
+ <para>
+ A producer method is declared by annotating a method of a bean class with the
<literal>@Produces</literal>
+ annotation.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@ApplicationScoped
+public class RandomNumberGenerator {
+
+ private Random random = new Random(System.currentTimeMillis());
+
+ @Produces @Named @Random int getRandomNumber() {
+ return random.nextInt(100);
+ }
+
+}]]></programlisting>
+
+ <para>
+ We can't write a bean class that is itself a random number. But we can
certainly write a method that returns
+ a random number. By making the method a producer method, we allow the return
value of the method—in this
+ case an <literal>Integer</literal>—to be injected. We
can even specify a qualifier—in this case
+ <literal>@Random</literal>, a scope—which in this case
defaults to <literal>@Dependent</literal>,
+ and an EL name—which in this case defaults to
<literal>randomNumber</literal> according to the JavaBeans
+ property name convention. Now we can get a random number anywhere:
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Inject @Random int
randomNumber;]]></programlisting>
+
+ <para>
+ Even in a Unified EL expression:
+ </para>
+
+ <programlisting><![CDATA[<p>Your raffle number is
#{randomNumber}.</p>]]></programlisting>
+
+ <para>
+ A producer method must be a non-abstract method of a managed bean class or
session bean class. A producer
+ method may be either static or non-static. If the bean is a session bean, the
producer method must be either
+ a business method of the EJB or a static method of the bean class.
+ </para>
+
+ <para>
+ The bean types of a producer method depend upon the method return type:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If the return type is an interface, the unrestricted set of bean types
contains the return type, all
+ interfaces it extends directly or indirectly and
<literal>java.lang.Object</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a return type is primitive or is a Java array type, the unrestricted
set of bean types contains
+ exactly two types: the method return type and
<literal>java.lang.Object</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the return type is a class, the unrestricted set of bean types
contains the return type, every
+ superclass and all interfaces it implements directly or indirectly.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ If the producer method has method parameters, the container will look for a
bean that satisfies the type
+ and qualifiers of each parameter and pass it to the method
automatically—another form of
+ dependency injection.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[@Produces Set<Roles>
getRoles(User user) {
+ return user.getRoles();
+}]]></programlisting>
+
+ <para>We'll talk much more about producer methods in <xref
linkend="producermethods"/>.</para>
+
+ </section>
+
+ <section>
+ <title>Producer fields</title>
+
+ <para>
+ A <emphasis>producer field</emphasis> is a simpler alternative to
a producer method. A producer field is
+ declared by annotating a field of a bean class with the
<literal>@Produces</literal> annotation—the
+ same annotation used for producer methods.
+ </para>
+
+ <programlisting role="JAVA"><![CDATA[public class Shop {
+ @Produces PaymentProcessor paymentProcessor = ....;
+ @Produces @Catalog List<Product> products = ....;
+}]]></programlisting>
+
+ <para>
+ The rules for determining the bean types of a producer field parallel the
rules for producer methods.
+ </para>
+
+ <para>
+ A producer field is really just a shortcut that lets us avoid writing a
useless getter method. However,
+ in addition to convenience, producer fields serve a specific purpose as an
adaptor for Java EE component
+ environment injection, but to learn more about that, you'll have to wait
until <xref linkend="resources"/>.
+ Because we can't wait to get to work on some examples.
+ </para>
+
+ </section>
+
+ </section>
+
+<!--
+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-10 07:50:26 UTC (rev 4947)
+++ doc/trunk/reference/en-US/intro.xml 2009-11-10 08:17:29 UTC (rev 4948)
@@ -1,7 +1,7 @@
<!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 CDI</title>
+ <title>Introduction</title>
<para>
So you're keen to get started writing your first bean? Or perhaps you're
skeptical, wondering what kinds of hoops
@@ -13,8 +13,7 @@
<title>What is a bean?</title>
<para>
- In this section, you'll learn that a bean is exactly what you think it is.
Only now, it has a true identity in
- the container environment.
+ A bean is exactly what you think it is. Only now, it has a true identity in the
container environment.
</para>
<para>
@@ -214,746 +213,6 @@
</section>
- <section id="bean-anatomy">
- <title>The anatomy of a bean</title>
-
- <para>
- A bean is usually an application class that contains business logic. It may be
called directly from Java code,
- or it may be invoked via the Unified EL. A bean may access transactional
resources. Dependencies between beans
- are 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>
- Let's back up a second. What does it really mean to be
<emphasis>contextual</emphasis>? Since beans may be
- stateful, it matters <emphasis>which</emphasis> bean instance I
have. Unlike a stateless component model (for
- example, stateless session beans) or a singleton component model (such as
servlets, or singleton beans),
- different clients of a bean see the bean in different states. The client-visible
state depends upon which
- instance of the bean the client has a reference to.
- </para>
-
- <para>
- However, like a stateless or singleton model, but
<emphasis>unlike</emphasis> stateful session beans, the
- client does not control the lifecycle of the instance by explicitly creating and
destroying it. Instead, the
- <emphasis>scope</emphasis> of the bean determines:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>the lifecycle of each instance of the bean and</para>
- </listitem>
- <listitem>
- <para>which clients share a reference to a particular instance of the
bean.</para>
- </listitem>
- </itemizedlist>
-
- <para>
- For a given thread in a CDI application, there may be an <emphasis>active
context</emphasis> associated with
- the scope of the bean. This context may be unique to the thread (for example, if
the bean is request scoped),
- or it may be shared with certain other threads (for example, if the bean is
session scoped) or even all other
- threads (if it is application scoped).
- </para>
-
- <para>
- Clients (for example, other beans) executing in the same context will see the
same instance of the bean. But
- clients in a different context may see a different instance (depending on the
relationship between the
- contexts).
- </para>
-
- <para>
- One great advantage of the contextual model is that it allows stateful beans to
be treated like services! The
- client need not concern itself with managing the lifecycle of the bean it's
using, <emphasis>nor does it even
- need to know what that lifecycle is.</emphasis> Beans interact by passing
messages, and the bean implementations
- define the lifecycle of their own state. The beans are loosely coupled because:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>they interact via well-defined public APIs</para>
- </listitem>
- <listitem>
- <para>their lifecycles are completely decoupled</para>
- </listitem>
- </itemizedlist>
-
- <para>
- We can replace one bean with another different bean that implements the same
interface and has a different lifecycle
- (a different scope) without affecting the other bean implementation. In fact,
CDI defines a simple facility for
- overriding bean implementations at deployment time, as we will see in <xref
linkend="alternatives"/>.
- </para>
-
- <para>
- Note that not all clients of a bean are beans themselves. Other objects such as
servlets or message-driven
- beans—which are by nature not injectable, contextual
objects—may also obtain references to beans by
- injection.
- </para>
-
- <para>Enough hand-waving. More formally, the anatomy of a bean, according to
the spec:</para>
-
- <blockquote>
-
- <para>A bean comprises the following attributes:</para>
-
- <itemizedlist>
- <listitem><para>A (nonempty) set of bean
types</para></listitem>
- <listitem><para>A (nonempty) set of
qualifiers</para></listitem>
- <listitem><para>A scope</para></listitem>
- <listitem><para>Optionally, a bean EL
name</para></listitem>
- <listitem><para>A set of interceptor
bindings</para></listitem>
- <listitem><para>A bean
implementation</para></listitem>
- </itemizedlist>
-
- <para>Furthermore, a bean may or may not be an alternative.</para>
-
- </blockquote>
-
- <para>Let's see what all this new terminology means.</para>
-
- <section>
- <title>Bean types, qualifiers and dependency injection</title>
-
- <para>
- Beans usually acquire references to other beans via dependency injection. Any
injected attribute specifies a
- "contract" that must be satisfied by the bean to be injected. The
contract is:
- </para>
-
- <itemizedlist>
- <listitem><para>a bean type, together
with</para></listitem>
- <listitem><para>a set of
qualifiers.</para></listitem>
- </itemizedlist>
-
- <para>
- A bean type is a user-defined class or interface; a type that is
client-visible. If the bean is an EJB
- session bean, the bean type is the <literal>@Local</literal>
interface or bean-class local view. A bean may
- have multiple bean types. For example, the following bean has four bean
types:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public class BookShop
- extends Business
- implements Shop<Book> {
- ...
-}]]></programlisting>
-
- <para>
- The bean types are <literal>BookShop</literal>,
<literal>Business</literal> and
- <literal>Shop<Book></literal>, as well as the
implicit type <literal>java.lang.Object</literal>.
- (Notice that a parameterized type is a legal bean type).
- </para>
-
- <para>
- Meanwhile, this session bean has only the local interfaces
<literal>BookShop</literal>,
- <literal>Auditable</literal> and
<literal>java.lang.Object</literal> as bean types, since the bean class,
- <literal>BookShopBean</literal> is not a client-visible type.
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Stateful
-public class BookShopBean
- extends Business
- implements BookShop, Auditable {
- ...
-}]]></programlisting>
-
- <note>
- <para>
- Most bean types you can probably figure out. One gotcha is primitive
types. All primitive types are assumed
- to be identical to their corresponding wrapper types in
<literal>java.lang</literal>.
- </para>
- </note>
-
- <para>
- Bean types may be restricted to an explicit set by annotating the bean with
the <literal>@Typed</literal>
- annotation and listing the classes that should be bean types. For instance,
the bean types of this bean have
- been restricted to <literal>Shop<Book></literal>,
together with <literal>java.lang.Object</literal>:
- </para>
-
- <programlisting role="JAVA"><![CDATA[(a)Typed(Shop.class)
-public class BookShop
- extends Business
- implements Shop<Book> {
- ...
-}]]></programlisting>
-
- <para>
- Sometimes, a bean type alone does not provide enough information for the
container to know which bean to inject.
- For instance, suppose we have two implementations of the
<literal>PaymentProcessor</literal> interface:
- <literal>CreditCardPaymentProcessor</literal> and
<literal>DebitPaymentProcessor</literal>. Injecting a field of
- type <literal>PaymentProcessor</literal> introduces an ambiguous
condition. In these cases, the client must
- specify some additional quality of the implementation it is interested in. We
model this kind of "quality" using
- a qualifier.
- </para>
-
- <para>
- A qualifier is a user-defined annotation that is itself annotated
<literal>@Qualifer</literal>. A qualifier
- annotation is an extension of the type system. It lets us disambiguate a type
without having to fall back to
- string-based names. Here's an example of a qualifier annotation:
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Qualifier
-@Target({TYPE, METHOD, PARAMETER, FIELD})
-@Retention(RUNTIME)
-public @interface CreditCard {}]]></programlisting>
-
- <para>
- You may not be used to seeing the definition of an annotation. In fact, this
might be the first time you've
- encountered one. With CDI, annotation definitions will become a familiar
artifact as you'll be creating them
- from time to time.
- </para>
-
- <tip>
- <para>
- Pay attention to the names of the built-in annotations in CDI and EJB.
You'll notice that they are
- often adjectives. We encourage you to follow this convention when creating
your custom annotations,
- since they serve to describe the behaviors and roles of the class.
- </para>
- </tip>
-
- <para>
- Now that we have defined a qualifier annotation, we can use it to
disambiguate an injection point. The
- following injection point has the bean type
<literal>PaymentProcessor</literal> and qualifier
- <literal>@CreditCard</literal>:
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Inject @CreditCard
PaymentProcessor paymentProcessor]]></programlisting>
-
- <note>
- <para>
- If an injection point does not explicitly specify a qualifier, it has the
default qualifier,
- <literal>@Default</literal>.
- </para>
- </note>
-
- <para>
- For each injection point, the container searches for a bean which satisfies
the contract, one which has
- the bean type and all the qualifiers. If it finds exactly one matching bean,
it injects an instance of
- that bean. If it doesn't, it reports an error to the user.
- </para>
-
- <para>
- How do we specify that qualifiers of a bean? By annotating the bean class, of
course! The following bean
- has the qualifier <literal>@CreditCard</literal> and implements
the bean type <literal>PaymentProcessor</literal>.
- Therefore, it satisfies our qualified injection point:
- </para>
-
- <programlisting role="JAVA"><![CDATA[@CreditCard
-public class CreditCardPaymentProcessor
- implements PaymentProcessor { ... }]]></programlisting>
-
- <note>
- <para>
- If a bean does not explicitly specify a qualifier, it has the default
qualifier, <literal>@Default</literal>.
- </para>
- </note>
-
- <!--
- <note>
- <para>
- All beans have the qualifier, <literal>@Any</literal>.
- </para>
- </note>
- -->
-
- <para>
- That's not quite the end of the story. CDI also defines a simple
<emphasis>resolution rule</emphasis> that helps
- the container decide what to do if there is more than one bean that satisfies
a particular contract. We'll get
- into the details in <xref linkend="injection"/>.
- </para>
-
- <!--
- <tip>
- <para>
- If you're expectng more than one bean to satisfy the contract, you can
inject an <literal>Instance</literal>,
- object which let's you iterate over all the beans which satisfy the
contract. For example, we can iterate
- over all our implementations of
<literal>PaymentProcessor</literal> using:
- </para>
- <programlisting>@Inject void init(@Any
Instance<PaymentProcessor> paymentProcessorInstance) {
- for (PaymentProcessor pp: paymentProcessorInstance) { ... }
-}</programlisting>
- </tip>
- -->
-
- </section>
-
- <section>
- <title>Scope</title>
- <!-- I wonder whether the explaination of contextual above would fit better
here -->
-
- <para>
- The <emphasis>scope</emphasis> of a bean defines the lifecycle
and visibility of its instances.
- The CDI context model is extensible, accommodating arbitrary scopes. However,
certain important scopes are
- built into the specification, and provided by the container. Each scope is
represented by an annotation
- type.
- </para>
-
- <para>
- For example, any web application may have <emphasis>session
scoped</emphasis> bean:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @SessionScoped
-class ShoppingCart implements Serializable { ... }]]></programlisting>
-
- <para>An instance of a session-scoped bean is bound to a user session
- and is shared by all requests that execute in the context of that
session.</para>
-
- <note>
- <para>
- Keep in mind that once a bean is bound to a context, it remains in that
context until the context is
- destroyed. There is no way to explicitly remove a bean from a context. If
you don't the bean to live in
- the session indefinitely, consider using another scope such as the request
or conversation scope instead.
- </para>
- </note>
-
- <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 object into which they
- were 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>
-
- </section>
-
- <section>
- <title>EL name</title>
-
- <para>
- If you want to reference a bean in non-Java code that supports Unified EL
expressions, for example, in a
- JSP or JSF page, you must assign the bean an <emphasis>EL
name</emphasis>.
- </para>
-
- <para>
- The EL name is specified using the <literal>@Named</literal>
annotation, as shown here:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Named("cart")
-class ShoppingCart implements Serializable { ... }]]></programlisting>
-
- <para>Now we can easily use the bean in any JSF or JSP page:</para>
-
- <programlisting role="XML"><![CDATA[<h:dataTable
value="#{cart.lineItems}" var="item">
- ...
-</h:dataTable>]]></programlisting>
-
- <note>
- <para>
- The <literal>@Named</literal> annotation is not what makes the
class a bean. Most classes in a bean
- archive are already recognized as beans. The
<literal>@Named</literal> annotation just makes it
- possible to reference the bean from the EL, most commonly from a JSF
view.
- </para>
- </note>
-
- <para>
- We can let CDI choose a name for us by leaving off the value of the
<literal>@Named</literal> annotation:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Named
-class ShoppingCart implements Serializable { ... }]]></programlisting>
-
- <para>
- The name defaults to the unqualified class name, decapitalized; in this
case,
- <literal>shoppingCart</literal>.
- </para>
-
- </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>
-
- <para>
- We've already seen how qualifiers let us choose between multiple
implementations of an interface
- at development time. But sometimes we have an interface (or other bean type)
whose implementation
- varies depending upon the deployment environment. For example, we may want to
use a mock
- implementation in a testing environment. An
<emphasis>alternative</emphasis> may be declared by
- annotating the bean class with the
<literal>@Alternative</literal> annotation.
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @Alternative
-class MockPaymentProcessor extends PaymentProcessorImpl { ...
}]]></programlisting>
-
- <para>
- We normally annotate a bean <literal>@Alternative</literal> only
when there is some other
- implementation of an interface it implements (or of any of its bean types).
We can choose between
- alternatives at deployment time by <emphasis>selecting</emphasis>
an alternative in the CDI
- deployment descriptor <literal>META-INF/beans.xml</literal> of
the jar or Java EE module that uses
- it. Different modules can specify that they use different alternatives.
- </para>
-
- <para>
- We cover alternatives in more detail in <xref
linkend="alternatives"/>.
- </para>
-
- </section>
-
- <section>
- <title>Interceptor binding types</title>
-
- <para>
- You might be familiar with the use of interceptors in EJB 3.0. In Java EE 6,
this functionality has
- been generalized to work with other managed beans. That's right, you no
longer have to make your bean
- an EJB just to intercept its methods. Holler. So what does CDI have to offer
above and beyond that? Well,
- quite a lot actually. Let's cover some background.
- </para>
-
- <para>
- The way that interceptors were defined in Java EE 5 was counter-intuitive.
You were required to specify the
- <emphasis>implementation</emphasis> of the interceptor directly
on the <emphasis>implementation</emphasis>
- of the EJB, either in the <literal>@Interceptors</literal>
annotation or in the XML descriptor. You might as
- well just put the interceptor code <emphasis>in</emphasis> the
implementation! Second, the order in which
- the interceptors are applied is taken from the order in which they are
declared in the annotation or the XML
- descriptor. Perhaps this isn't so bad if you're applying the
interceptors to a single bean. But, if you are
- applying them repeatedly, then there's a good chance that you'll
inadvertently define a different order for
- different beans. Now that's a problem.
- </para>
-
- <para>
- CDI provides a new approach to binding interceptors to beans that introduces
a level of indirection (and
- thus control). We must define an <emphasis>interceptor binding
type</emphasis> to describe the behavior
- implemented by the interceptor.
- </para>
-
- <para>
- An interceptor binding type is a user-defined annotation that is itself
annotated <literal>@InterceptorBinding</literal>.
- It lets us bind interceptor classes to bean classes with no direct dependency
between the two classes.
- </para>
-
- <programlisting role="JAVA"><![CDATA[@InterceptorBinding
-@Inherited
-@Target( { TYPE, METHOD })
-@Retention(RUNTIME)
-public @interface Transactional {}]]></programlisting>
-
- <para>
- The interceptor that implements transaction management declares this
annotation:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @Transactional
@Interceptor
-class TransactionInterceptor { ... }]]></programlisting>
-
- <para>
- We can apply the interceptor to a bean by annotating the bean class with the
same interceptor binding type:
- </para>
-
- <programlisting role="JAVA"><![CDATA[public @SessionScoped
@Transactional
-class ShoppingCart implements Serializable { ... }]]></programlisting>
-
- <para>
- Notice that <literal>ShoppingCart</literal> and
<literal>TransactionInterceptor</literal> don't know
- anything about each other.
- </para>
-
- <para>
- Interceptors are deployment-specific. (We don't need a
<literal>TransactionInterceptor</literal> in our
- unit tests!) By default, an interceptor is disabled. We can enable an
interceptor using the CDI deployment
- descriptor <literal>META-INF/beans.xml</literal> of the jar or
Java EE module. This is also where we
- specify the interceptor ordering.
- </para>
-
- <para>
- We'll discuss interceptors, and their cousins, decorators, in <xref
linkend="interceptors"/> and <xref
- linkend="decorators"/>.
- </para>
-
- </section>
-
- </section>
-
- <section>
- <title>What kinds of classes are beans?</title>
-
- <para>
- We've already seen two types of beans: JavaBeans and EJB session beans. Is
that the whole story? Actually,
- it's just the beginning. Let's explore the various kinds of beans that
CDI implementations must support
- out-of-the-box.
- </para>
-
- <section>
- <title>Managed beans</title>
-
- <para>
- A managed bean is a Java class. The basic lifecycle and semantics of a
managed bean are defined by the
- Managed Beans specification. You can explicitly declare a managed bean by
annotating the bean class
- <literal>@ManagedBean</literal>, but in CDI you don't need
to. According to the specification, the CDI
- container treats any class that satisfies the following conditions as a
managed bean:
- </para>
-
- <blockquote>
-
- <itemizedlist>
- <listitem>
- <para>It is not a non-static inner class.</para>
- </listitem>
- <listitem>
- <para>It is a concrete class, or is annotated
<literal>(a)Decorator</literal>.</para>
- </listitem>
- <listitem>
- <para>
- It is not annotated with an EJB component-defining annotation or
declared as an EJB bean class in
- <literal>ejb-jar.xml</literal>.
- </para>
- </listitem>
- <listitem>
- <para>It does not implement
<literal>javax.enterprise.inject.spi.Extension</literal>.</para>
- </listitem>
- <listitem>
- <para>
- It has an appropriate constructor—either:
- </para>
- <itemizedlist>
- <listitem>
- <para>the class has a constructor with no parameters,
or</para>
- </listitem>
- <listitem>
- <para>the class declares a constructor annotated
<literal>(a)Inject</literal>.</para>
- </listitem>
- </itemizedlist>
- </listitem>
- </itemizedlist>
-
- </blockquote>
-
- <para>The unrestricted set of bean types for a managed bean contains the
bean class, every superclass and all
- interfaces it implements directly or indirectly.</para>
-
- <para>If a managed bean has a public field, it must have the default scope
<literal>(a)Dependent</literal>.</para>
-
- <para>Managed beans support the
<literal>@PostConstruct</literal> and
<literal>@PreDestroy</literal> lifecycle
- callbacks.</para>
-
- <para>
- Session beans are also, technically, managed beans. However, since they have
their own special lifecycle and
- take advantage of additional enterprise services, the CDI specification
considers them to be a different
- kind of bean.
- </para>
-
- </section>
-
- <section>
- <title>Session beans</title>
-
- <para>
- Session beans belong to the EJB specification. They have a special lifecycle,
state management and concurrency
- model that is different to other managed beans and non-managed Java objects.
But session beans participate in
- CDI just like any other bean. You can inject one session bean into another
session bean, a managed bean into a
- session bean, a session bean into a managed bean, have a managed bean observe
an event raised by a session bean,
- and so on.
- </para>
-
- <note>
- <para>
- Message-driven and entity beans are by nature non-contextual objects and
may not be injected into other
- objects. However, message-driven beans can take advantage of some CDI
functionality, such as dependency
- injection, interceptors and decorators. In fact, CDI will perform
injection into any session or
- message-driven bean, even those which are not contextual instances.
- </para>
- </note>
-
- <para>
- The unrestricted set of bean types for a session bean contains all local
interfaces of the bean and their
- superinterfaces. If the session bean has a bean class local view, the
unrestricted set of bean types
- contains the bean class and all superclasses. In addition,
<literal>java.lang.Object</literal> is a bean
- type of every session bean. But remote interfaces are
<emphasis>not</emphasis> included in the set of bean
- types.
- </para>
-
- <para>There's no reason to explicitly declare the scope of a stateless
session bean or singleton session bean.
- The EJB container controls the lifecycle of these beans, according to the
semantics of the <literal>@Stateless</literal>
- or <literal>@Singleton</literal> declaration. On the other hand, a
stateful session bean may have any scope.</para>
-
- <para>
- Stateful session beans may define a <emphasis>remove
method</emphasis>, annotated <literal>@Remove</literal>,
- that is used by the application to indicate that an instance should be
destroyed. However, for a contextual
- instance of the bean—an instance under the control of
CDI—this method may only be called by the
- application if the bean has scope <literal>@Dependent</literal>.
For beans with other scopes, the application
- must let the container destroy the bean.
- </para>
-
- <para>
- So, when should we use a session bean instead of a plain managed bean?
Whenever we need the advanced enterprise
- services offered by EJB, such as:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>method-level transaction management and security,</para>
- </listitem>
- <listitem>
- <para>concurrency management,</para>
- </listitem>
- <listitem>
- <para>instance-level passivation for stateful session beans and
- instance-pooling for stateless session beans,</para>
- </listitem>
- <listitem>
- <para>remote or web service invocation, or</para>
- </listitem>
- <listitem>
- <para>timers and asynchronous methods,</para>
- </listitem>
- </itemizedlist>
-
- <para>When we don't need any of these things, an ordinary managed bean
will serve just fine.</para>
-
- <para>
- Many beans (including any <literal>@SessionScoped</literal> or
<literal>@ApplicationScoped</literal>
- beans) are available for concurrent access. Therefore, the concurrency
management provided by EJB 3.1
- is especially useful. Most session and application scoped beans should be
EJBs.
- </para>
-
- <para>
- Beans which hold references to heavy-weight resources, or hold a lot of
internal state benefit from the
- advanced container-managed lifecycle defined by the EJB
stateless/stateful/singleton model, with its
- support for passivation and instance pooling.
- </para>
-
- <para>
- Finally, it's usually obvious when method-level transaction management,
method-level security, timers,
- remote methods or asynchronous methods are needed.
- </para>
-
- <para>
- The point we're trying to make is: use a session bean when you need the
services it provides, not just
- because you want to use dependency injection, lifecycle management, or
interceptors. Java EE 6 provides
- a graduated programming model. It's usually easy to start with an
ordinary managed bean, and later turn
- it into an EJB just by adding one of the following annotations:
<literal>@Stateless</literal>,
- <literal>@Stateful</literal> or
<literal>@Singleton</literal>.
- </para>
-
- <para>
- On the other hand, don't be scared to use session beans just because
you've heard your friends say
- they're "heavyweight". It's nothing more than superstition
to think that something is "heavier" just
- because it's hosted natively within the Java EE container, instead of by
a proprietary bean container
- or dependency injection framework that runs as an additional layer of
obfuscation. And as a general
- principle, you should be skeptical of folks who use vaguely defined
terminology like "heavyweight".
- </para>
-
- </section>
-
- <section>
- <title>Producer methods</title>
-
- <para>
- Not everything that needs to be injected can be boiled down to a bean class
instantiated by the container
- using <literal>new</literal>. There are plenty of cases where we
need additional control. What if we need
- to decide at runtime which implementation of a type to instantiate and
inject? What if we need to inject
- an object that is obtained by querying a service or transactional resource,
for example by executing a JPA
- query?
- </para>
-
- <para>
- A <emphasis>producer method</emphasis> is a method that acts as a
source of bean instances. The method
- declaration itself describes the bean and the container invokes the method to
obtain an instance of the
- bean when no instance exists in the specified context. A producer method lets
the application take full
- control of the bean instantiation process.
- </para>
-
- <para>
- A producer method is declared by annotating a method of a bean class with the
<literal>@Produces</literal>
- annotation.
- </para>
-
- <programlisting role="JAVA"><![CDATA[@ApplicationScoped
-public class RandomNumberGenerator {
-
- private Random random = new Random(System.currentTimeMillis());
-
- @Produces @Named @Random int getRandomNumber() {
- return random.nextInt(100);
- }
-
-}]]></programlisting>
-
- <para>
- We can't write a bean class that is itself a random number. But we can
certainly write a method that returns
- a random number. By making the method a producer method, we allow the return
value of the method—in this
- case an <literal>Integer</literal>—to be injected. We
can even specify a qualifier—in this case
- <literal>@Random</literal>, a scope—which in this case
defaults to <literal>@Dependent</literal>,
- and an EL name—which in this case defaults to
<literal>randomNumber</literal> according to the JavaBeans
- property name convention. Now we can get a random number anywhere:
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Inject @Random int
randomNumber;]]></programlisting>
-
- <para>
- Even in a Unified EL expression:
- </para>
-
- <programlisting><![CDATA[<p>Your raffle number is
#{randomNumber}.</p>]]></programlisting>
-
- <para>
- A producer method must be a non-abstract method of a managed bean class or
session bean class. A producer
- method may be either static or non-static. If the bean is a session bean, the
producer method must be either
- a business method of the EJB or a static method of the bean class.
- </para>
-
- <para>
- The bean types of a producer method depend upon the method return type:
- </para>
-
- <itemizedlist>
- <listitem>
- <para>
- If the return type is an interface, the unrestricted set of bean types
contains the return type, all
- interfaces it extends directly or indirectly and
<literal>java.lang.Object</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- If a return type is primitive or is a Java array type, the unrestricted
set of bean types contains
- exactly two types: the method return type and
<literal>java.lang.Object</literal>.
- </para>
- </listitem>
- <listitem>
- <para>
- If the return type is a class, the unrestricted set of bean types
contains the return type, every
- superclass and all interfaces it implements directly or indirectly.
- </para>
- </listitem>
- </itemizedlist>
-
- <para>
- If the producer method has method parameters, the container will look for a
bean that satisfies the type
- and qualifiers of each parameter and pass it to the method
automatically—another form of
- dependency injection.
- </para>
-
- <programlisting role="JAVA"><![CDATA[@Produces Set<Roles>
getRoles(User user) {
- return user.getRoles();
-}]]></programlisting>
-
- <para>We'll talk much more about producer methods in <xref
linkend="producermethods"/>.</para>
-
- </section>
-
- <section>
- <title>Producer fields</title>
-
- <para>
- A <emphasis>producer field</emphasis> is a simpler alternative to
a producer method. A producer field is
- declared by annotating a field of a bean class with the
<literal>@Produces</literal> annotation—the
- same annotation used for producer methods.
- </para>
-
- <programlisting role="JAVA"><![CDATA[public class Shop {
- @Produces PaymentProcessor paymentProcessor = ....;
- @Produces @Catalog List<Product> products = ....;
-}]]></programlisting>
-
- <para>
- The rules for determining the bean types of a producer field parallel the
rules for producer methods.
- </para>
-
- <para>
- A producer field is really just a shortcut that lets us avoid writing a
useless getter method. However,
- in addition to convenience, producer fields serve a specific purpose as an
adaptor for Java EE component
- environment injection, but to learn more about that, you'll have to wait
until <xref linkend="resources"/>.
- Because we can't wait to get to work on some examples.
- </para>
-
- </section>
-
- </section>
-
<!--
vim:et:ts=3:sw=3:tw=120
-->
Modified: doc/trunk/reference/en-US/master.xml
===================================================================
--- doc/trunk/reference/en-US/master.xml 2009-11-10 07:50:26 UTC (rev 4947)
+++ doc/trunk/reference/en-US/master.xml 2009-11-10 08:17:29 UTC (rev 4948)
@@ -38,40 +38,33 @@
<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="beans.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="injection.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="scopescontexts.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <!-- TODO <xi:include href="producerfields.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" /> -->
</part>
- <part id="1.5">
+ <part id="2">
<title>Weld, the CDI Reference Implementation</title>
- <xi:include href="part1.5.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="part2.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="weldexamples.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
</part>
- <part id="2">
- <title>Developing loosely-coupled code</title>
+ <part id="3">
+ <title>Loose coupling with strong typing</title>
- <xi:include href="part2.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
+ <xi:include href="part3.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="producermethods.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" />
-
- </part>
-
- <part id="3">
- <title>Making the most of strong typing</title>
- <xi:include href="part3.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
<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="resources.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
Modified: doc/trunk/reference/en-US/part2.xml
===================================================================
--- doc/trunk/reference/en-US/part2.xml 2009-11-10 07:50:26 UTC (rev 4947)
+++ doc/trunk/reference/en-US/part2.xml 2009-11-10 08:17:29 UTC (rev 4948)
@@ -3,64 +3,16 @@
<partintro>
<para>
- The first major theme of CDI is <emphasis>loose coupling</emphasis>.
We've already seen three means of achieving
- loose coupling:
+ Weld, the JSR-299 Reference Implementation (RI), is being developed as part of the
<ulink
+
url="http://seamframework.org/Weld">Seam project</ulink>. You
can download the latest community release of Weld
+ from the <ulink
url="http://seamframework.org/Download">download
page</ulink>. Information about the Weld source
+ code repository and instructions about how to obtain and build the source can be
found on the same page.
</para>
-
- <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 interface, nor is it required to manage the lifecycle of the
implementation. This approach
- lets <emphasis>stateful objects interact as if they were
services</emphasis>.
+ Weld comes with an extensive library of examples, which are a great starting point
from which to learn CDI.
</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>
- 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>
-
- <para>Let's explore producer methods first.</para>
-
+
<!--
vim:et:ts=3:sw=3:tw=120
-->
Modified: doc/trunk/reference/en-US/part3.xml
===================================================================
--- doc/trunk/reference/en-US/part3.xml 2009-11-10 07:50:26 UTC (rev 4947)
+++ doc/trunk/reference/en-US/part3.xml 2009-11-10 08:17:29 UTC (rev 4948)
@@ -1,8 +1,65 @@
<!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 CDI is <emphasis>loose coupling</emphasis>.
We've already seen three means of achieving
+ loose coupling:
+ </para>
+
+ <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 interface, nor is it required to manage the lifecycle of the
implementation. 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 (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>
+ 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>
+
+ <para>
The second major theme of CDI 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.
@@ -84,7 +141,7 @@
<emphasis>need</emphasis> to use these features, but if you use them
wisely, you'll come to appreciate their
power.
</para>
-
+
<!--
vim:et:ts=3:sw=3:tw=120
-->