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 stateful and
contextual. The lifecycle of a bean is always managed by the container.

Let's back up a second. What does it really mean to be contextual? Since beans may be
stateful, it matters which 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.

However, like a stateless or singleton model, but unlike stateful session beans, the
client does not control the lifecycle of the instance by explicitly creating and destroying it. Instead, the
scope of the bean determines:

the lifecycle of each instance of the bean and

which clients share a reference to a particular instance of the bean.

For a given thread in a CDI application, there may be an active context 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).

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).

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, nor does it even
need to know what that lifecycle is. Beans interact by passing messages, and the bean implementations
define the lifecycle of their own state. The beans are loosely coupled because:

they interact via well-defined public APIs

their lifecycles are completely decoupled

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 Section 4.7, “Alternatives”.

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.

2.1. The anatomy of a bean

Enough hand-waving. More formally, the anatomy of a bean, according to the spec:

A bean comprises the following attributes:

A (nonempty) set of bean types

A (nonempty) set of qualifiers

A scope

Optionally, a bean EL name

A set of interceptor bindings

A bean implementation

Furthermore, a bean may or may not be an alternative.

Let's see what all this new terminology means.

2.1.1. Bean types, qualifiers and dependency injection

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:

a bean type, together with

a set of qualifiers.

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 @Local interface or bean-class local view. A bean
may have multiple bean types. For example, the following bean has four bean types:

publicclassBookShopextendsBusinessimplementsShop<Book>{...}

The bean types are BookShop, Business and
Shop<Book>, as well as the implicit type java.lang.Object.
(Notice that a parameterized type is a legal bean type).

Meanwhile, this session bean has only the local interfaces BookShop,
Auditable and java.lang.Object as bean types, since the bean class,
BookShopBean is not a client-visible type.

Note

The bean types of a session bean include local interfaces and the bean class local view (if any).
EJB remote interfaces are not considered bean types of a session bean. You can't inject an EJB using
its remote interface unless you define a resource, which we'll meet in
Chapter 14, Java EE component environment resources.

Bean types may be restricted to an explicit set by annotating the bean with the @Typed
annotation and listing the classes that should be bean types. For instance, the bean types of this bean have
been restricted to Shop<Book>, together with java.lang.Object:

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 PaymentProcessor interface:
CreditCardPaymentProcessor and DebitPaymentProcessor. Injecting a field of
type PaymentProcessor 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.

A qualifier is a user-defined annotation that is itself annotated @Qualifer. 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:

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.

Tip

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.

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 PaymentProcessor and qualifier
@CreditCard:

@Inject @CreditCardPaymentProcessor paymentProcessor

Note

If an injection point does not explicitly specify a qualifier, it has the default qualifier,
@Default.

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.

How do we specify that qualifiers of a bean? By annotating the bean class, of course! The following bean
has the qualifier @CreditCard and implements the bean type PaymentProcessor.
Therefore, it satisfies our qualified injection point:

Note

If a bean does not explicitly specify a qualifier, it has the default qualifier, @Default.

That's not quite the end of the story. CDI also defines a simple resolution rule 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 Chapter 4, Dependency injection and programmatic lookup.

2.1.2. Scope

The scope 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.

For example, any web application may have session scoped bean:

public @SessionScopedclassShoppingCartimplementsSerializable{...}

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.

Note

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 manually remove a bean from a context. If you don't want the bean to sit
in the session indefinitely, consider using another scope with a shorted lifespan, such as the request
or conversation scope.

If a scope is not explicitly specified, then the bean belongs to a special scope called the
dependent pseudo-scope. 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.

2.1.3. EL name

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 EL name.

The EL name is specified using the @Named annotation, as shown here:

public @SessionScoped @Named("cart")classShoppingCartimplementsSerializable{...}

Now we can easily use the bean in any JSF or JSP page:

<h:dataTablevalue="#{cart.lineItems}"var="item"> ...</h:dataTable>

Note

The @Named annotation is not what makes the class a bean. Most classes in a bean
archive are already recognized as beans. The @Named annotation just makes it
possible to reference the bean from the EL, most commonly from a JSF view.

We can let CDI choose a name for us by leaving off the value of the @Named annotation:

public @SessionScoped @NamedclassShoppingCartimplementsSerializable{...}

The name defaults to the unqualified class name, decapitalized; in this case,
shoppingCart.

2.1.4. Alternatives

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 alternative may be declared by
annotating the bean class with the @Alternative annotation.

public @AlternativeclassMockPaymentProcessorextendsPaymentProcessorImpl{...}

We normally annotate a bean @Alternative 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 selecting an alternative in the CDI
deployment descriptor META-INF/beans.xml of the jar or Java EE module that uses
it. Different modules can specify that they use different alternatives.

2.1.5. Interceptor binding types

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.

The way that interceptors were defined in Java EE 5 was counter-intuitive. You were required to specify the
implementation of the interceptor directly on the implementation
of the EJB, either in the @Interceptors annotation or in the XML descriptor. You might as
well just put the interceptor code in 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.

CDI provides a new approach to binding interceptors to beans that introduces a level of indirection (and
thus control). We must define an interceptor binding type to describe the behavior
implemented by the interceptor.

An interceptor binding type is a user-defined annotation that is itself annotated @InterceptorBinding.
It lets us bind interceptor classes to bean classes with no direct dependency between the two classes.

The interceptor that implements transaction management declares this annotation:

public @Transactional @InterceptorclassTransactionInterceptor{...}

We can apply the interceptor to a bean by annotating the bean class with the same interceptor binding type:

public @SessionScoped @TransactionalclassShoppingCartimplementsSerializable{...}

Notice that ShoppingCart and TransactionInterceptor don't know
anything about each other.

Interceptors are deployment-specific. (We don't need a TransactionInterceptor in our
unit tests!) By default, an interceptor is disabled. We can enable an interceptor using the CDI deployment
descriptor META-INF/beans.xml of the jar or Java EE module. This is also where we
specify the interceptor ordering.

2.2. What kinds of classes are beans?

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.

2.2.1. Managed beans

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
@ManagedBean, 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:

It is not a non-static inner class.

It is a concrete class, or is annotated @Decorator.

It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in
ejb-jar.xml.

It does not implement javax.enterprise.inject.spi.Extension.

It has an appropriate constructor—either:

the class has a constructor with no parameters, or

the class declares a constructor annotated @Inject.

Note

According to this definition, JPA entities are technically managed beans. However, entities have their own
special lifecycle, state and identity model and are usually instantiated by JPA or using new.
Therefore we don't recommend directly injecting an entity class. We especially recommend against assigning
a scope other than @Dependent to an entity class, since JPA is not able to persist
injected CDI proxies.

The unrestricted set of bean types for a managed bean contains the bean class, every superclass and all
interfaces it implements directly or indirectly.

If a managed bean has a public field, it must have the default scope @Dependent.

Managed beans support the @PostConstruct and @PreDestroy lifecycle
callbacks.

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.

2.2.2. Session beans

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.

Note

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.

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, java.lang.Object is a bean
type of every session bean. But remote interfaces are not included in the set of bean
types.

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 @Stateless
or @Singleton declaration. On the other hand, a stateful session bean may have any scope.

Stateful session beans may define a remove method, annotated @Remove,
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 @Dependent. For beans with other scopes, the application
must let the container destroy the bean.

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:

When we don't need any of these things, an ordinary managed bean will serve just fine.

Many beans (including any @SessionScoped or @ApplicationScoped
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.

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.

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: @Stateless,
@Stateful or @Singleton.

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".

2.2.3. Producer methods

Not everything that needs to be injected can be boiled down to a bean class instantiated by the container
using new. 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?

A producer method 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.

A producer method is declared by annotating a method of a bean class with the @Produces
annotation.

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 Integer—to be injected. We can even specify a qualifier—in this case
@Random, a scope—which in this case defaults to @Dependent,
and an EL name—which in this case defaults to randomNumber according to the JavaBeans
property name convention. Now we can get a random number anywhere:

@Inject @Randomint randomNumber;

Even in a Unified EL expression:

<p>Your raffle number is #{randomNumber}.</p>

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.

The bean types of a producer method depend upon the method return type:

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 java.lang.Object.

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 java.lang.Object.

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.

Note

Producer methods and fields may have a primitive bean type. For the purpose of resolving dependencies,
primitive types are considered to be identical to their corresponding wrapper types in
java.lang.

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.

2.2.4. Producer fields

A producer field is a simpler alternative to a producer method. A producer field is
declared by annotating a field of a bean class with the @Produces annotation—the
same annotation used for producer methods.

The rules for determining the bean types of a producer field parallel the rules for producer methods.

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 Chapter 14, Java EE component environment resources.
Because we can't wait to get to work on some examples.