Chapter 1. Getting started with Web Beans

So you're already keen to get started writing your first Web Bean? Or perhaps you're skeptical, wondering what kinds of hoops the Web Beans specification will make you jump through! The good news is that you've probably already written and used hundreds, perhaps thousands of Web Beans. You might not even remember the first Web Bean you wrote.

1.1. Your first Web Bean

With certain, very special exceptions, every Java class with a constructor that accepts no parameters is a Web Bean. That includes every JavaBean. Furthermore, every EJB 3-style session or singleton bean is a Web Bean. Sure, the JavaBeans and EJBs you've been writing every day have not been able to take advantage of the new services defined by the Web Beans specification, but you'll be able to use every one of them as Web Beans—injecting them into other Web Beans, configuring them via the Web Beans XML configuration facility, even adding interceptors and decorators to them—without touching your existing code.

Suppose that we have two existing Java classes, that we've been using for years in various applications. The first class parses a string into a list of sentences:

public class SentenceParser {
    public List<String> parse(String text) { ... }

The second existing class is a stateless session bean front-end for an external system that is able to translate sentences from one language to another:

public class SentenceTranslator implements Translator {
    public String translate(String sentence) { ... }

Where Translator is the local interface:

public interface Translator {
    public String translate(String sentence);

Unfortunately, we don't have a pre-existing class that translates whole text documents. So let's write a Web Bean that does this job:

public class TextTranslator {
    private SentenceParser sentenceParser;
    private Translator sentenceTranslator;
    TextTranslator(SentenceParser sentenceParser, Translator sentenceTranslator) {
        this.sentenceParser = sentenceParser;
        this.sentenceTranslator = sentenceTranslator;
    public String translate(String text) {
        StringBuilder sb = new StringBuilder();
        for (String sentence in sentenceParser.parse(text)) {
        return sb.toString();

We may obtain an instance of TextTranslator by injecting it into a Web Bean, Servlet or EJB:

public setTextTranslator(TextTranslator textTranslator) {
    this.textTranslator = textTranslator;

Alternatively, we may obtain an instance by directly calling a method of the Web Bean manager:

TextTranslator tt = manager.getInstanceByType(TextTranslator.class);

But wait: TextTranslator does not have a constructor with no parameters! Is it still a Web Bean? Well, a class that does not have a constructor with no parameters can still be a Web Bean if it has a constructor annotated @Initializer.

As you've guessed, the @Initializer annotation has something to do with dependency injection! @Initializer may be applied to a constructor or method of a Web Bean, and tells the Web Bean manager to call that constructor or method when instantiating the Web Bean. The Web Bean manager will inject other Web Beans to the parameters of the constructor or method.

At system initialization time, the Web Bean manager must validate that exactly one Web Bean exists which satisfies each injection point. In our example, if no implementation of Translator available—if the SentenceTranslator EJB was not deployed—the Web Bean manager would throw an UnsatisfiedDependencyException. If more than one implementation of Translator was available, the Web Bean manager would throw an AmbiguousDependencyException.

1.2. What is a Web Bean?

So what, exactly, is a Web Bean?

A Web Bean is an application class that contains business logic. A Web Bean may be called directly from Java code, or it may be invoked via Unified EL. A Web Bean may access transactional resources. Dependencies between Web Beans are managed automatically by the Web Bean manager. Most Web Beans are stateful and contextual. The lifecycle of a Web Bean is always managed by the Web Bean manager.

Let's back up a second. What does it really mean to be "contextual"? Since Web 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 Web Bean see the Web Bean in different states. The client-visible state depends upon which instance of the Web 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 Web Bean determines:

  • the lifecycle of each instance of the Web Bean and

  • which clients share a reference to a particular instance of the Web Bean.

For a given thread in a Web Beans application, there may be an active context associated with the scope of the Web Bean. This context may be unique to the thread (for example, if the Web Bean is request scoped), or it may be shared with certain other threads (for example, if the Web Bean is session scoped) or even all other threads (if it is application scoped).

Clients (for example, other Web Beans) executing in the same context will see the same instance of the Web Bean. But clients in a different context will see a different instance.

One great advantage of the contextual model is that it allows stateful Web Beans to be treated like services! The client need not concern itself with managing the lifecycle of the Web Bean it is using, nor does it even need to know what that lifecyle is. Web Beans interact by passing messages, and the Web Bean implementations define the lifecycle of their own state. The Web Beans are loosely coupled because:

  • they interact via well-defined public APIs

  • their lifecycles are completely decoupled

We can replace one Web Bean with a different Web Bean that implements the same API and has a different lifecycle (a different scope) without affecting the other Web Bean implementation. In fact, Web Beans defines a sophisticated facility for overriding Web Bean implementations at deployment time, as we will see in Section 3.2, “Deployment types”.

Note that not all clients of a Web Bean are Web Beans. Other objects such as Servlets or Message-Driven Beans—which are by nature not injectable, contextual objects—may also obtain references to Web Beans by injection.

Enough hand-waving. More formally, according to the spec:

A Web Bean comprises:

  • A (nonempty) set of API types

  • A (nonempty) set of binding annotation types

  • A scope

  • A deployment type

  • Optionally, a Web Bean name

  • A set of interceptor binding types

  • A Web Bean implementation

Let's see what some of these terms mean, to the Web Bean developer.

1.2.1. API types, binding types and dependency injection

Web Beans usually acquire references to other Web Beans via dependency injection. Any injected attribute specifies a "contract" that must be satisfied by the Web Bean to be injected. The contract is:

  • an API type, together with

  • a set of binding types.

An API is a user-defined class or interface. (If the Web Bean is an EJB session bean, the API type is the @Local interface or bean-class local view). A binding type represents some client-visible semantic that is satisfied by some implementations of the API and not by others.

Binding types are represented by user-defined annotations that are themselves annotated @BindingType. For example, the following injection point has API type PaymentProcessor and binding type @CreditCard:

@CreditCard PaymentProcessor paymentProcessor

If no binding type is explicitly specified at an injection point, the default binding type @Current is assumed.

For each injection point, the Web Bean manager searches for a Web Bean which satisfies the contract (implements the API, and has all the binding types), and injects that Web Bean.

The following Web Bean has the binding type @CreditCard and implements the API type PaymentProcessor. It could therefore be injected to the example injection point:

public class CreditCardPaymentProcessor 
    implements PaymentProcessor { ... }

If a Web Bean does not explicitly specify a set of binding types, it has exactly one binding type: the default binding type @Current.

Web Beans defines a sophisticated but intuitive resolution algorithm that helps the container decide what to do if there is more than one Web Bean that satisfies a particular contract. We'll get into the details in Chapter 3, Dependency injection.

1.2.2. Deployment types

Deployment types let us classify our Web Beans by deployment scenario. A deployment type is an annotation that represents a particular deployment scenario, for example @Mock, @Staging or @AustralianTaxLaw. We apply the annotation to Web Beans which should be deployed in that scenario. A deployment type allows a whole set of Web Beans to be conditionally deployed, with a just single line of configuration.

Many Web Beans just use the default deployment type @Production, in which case no deployment type need be explicitly specified. All three Web Bean in our example have the deployment type @Production.

In a testing environment, we might want to replace the SentenceTranslator Web Bean with a "mock object":

public class MockSentenceTranslator implements Translator {
    public String translate(String sentence) {
        return "Lorem ipsum dolor sit amet";

We would enable the deployment type @Mock in our testing environment, to indicate that MockSentenceTranslator and any other Web Bean annotated @Mock should be used.

We'll talk more about this unique and powerful feature in Section 3.2, “Deployment types”.

1.2.3. Scope

The scope defines the lifecycle and visibility of instances of the Web Bean. The Web Beans context model is extensible, accommodating arbitrary scopes. However, certain important scopes are built-in to the specification, and provided by the Web Bean manager. A scope is represented by an annotation type.

For example, any web application may have session scoped Web Beans:

public class ShoppingCart { ... }

An instance of a session scoped Web Bean is bound to a user session and is shared by all requests that execute in the context of that session.

By default, Web Beans belong to a special scope called the dependent pseudo-scope. Web Beans with this scope are pure dependent objects of the object into which they are injected, and their lifecycle is bound to the lifecycle of that object.

We'll talk more about scopes in Chapter 4, Scopes and contexts.

1.2.4. Web Bean names and Unified EL

A Web Bean may have a name, allowing it to be used in Unified EL expressions. It's easy to specify the name of a Web Bean:

@SessionScoped @Named("cart")
public class ShoppingCart { ... }

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

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

It's even easier to just let the name be defaulted by the Web Bean manager:

@SessionScoped @Named
public class ShoppingCart { ... }

In this case, the name defaults to shoppingCart—the unqualified class name, with the first character changed to lowercase.

1.2.5. Interceptor binding types

Web Beans supports the interceptor functionality defined by EJB 3, not only for EJB beans, but also for plain Java classes. In addition, Web Beans provides a new approach to binding interceptors to EJB beans and other Web Beans.

It remains possible to directly specify the interceptor class via use of the @Interceptors annotation:

public class ShoppingCart { ... }

However, it is more elegant, and better practice, to indirect the interceptor binding through an interceptor binding type:

@SessionScoped @Transactional
public class ShoppingCart { ... }

We'll discuss Web Beans interceptors and decorators in Chapter 6, Interceptors and Chapter 7, Decorators.

1.3. What kinds of objects can be Web Beans?

We've already seen that JavaBeans, EJBs and some other Java classes can be Web Beans. But exactly what kinds of objects are Web Beans?

1.3.1. Simple Web Beans

The Web Beans specification says that a concrete Java class is a simple Web Bean if:

  • it is not an EE container-managed component, like an EJB, a Servlet or a JPA entity,

  • it is not a non-static static inner class,

  • it is not a parameterized type, and

  • it has a constructor with no parameters, or a constructor annotated @Initializer.

Thus, almost every JavaBean is a simple Web Bean.

Every interface implemented directly or indirectly by a simple Web Bean is an API type of the simple Web Bean. The class and its superclasses are also API types.

1.3.2. Enterprise Web Beans

The specification says that all EJB 3-style session and singleton beans are enterprise Web Beans. Message driven beans are not Web Beans—since they are not intended to be injected into other objects—but they can take advantage of most of the functionality of Web Beans, including dependency injection and interceptors.

Every local interface of an enterprise Web Bean that does not have a wildcard type parameter or type variable, and every one of its superinterfaces, is an API type of the enterprise Web Bean. If the EJB bean has a bean class local view, the bean class, and every one of its superclasses, is also an API type.

Stateful session beans should declare a remove method with no parameters or a remove method annotated @Destructor. The Web Bean manager calls this method to destroy the stateful session bean instance at the end of its lifecycle. This method is called the destructor method of the enterprise Web Bean.

@Stateful @SessionScoped
public class ShoppingCart {

    public void destroy() {}


So when should we use an enterprise Web Bean instead of a simple Web Bean? Well, whenever we need the advanced enterprise services offered by EJB, such as:

  • method-level transaction management and security,

  • concurrency management,

  • instance-level passivation for stateful session beans and instance-pooling for stateless session beans,

  • remote and web service invocation, and

  • timers and asynchronous methods,

we should use an enterprise Web Bean. When we don't need any of these things, a simple Web Bean will serve just fine.

Many Web Beans (including any session or application scoped Web Bean) are available for concurrent access. Therefore, the concurrency management provided by EJB 3.1 is especially useful. Most session and application scoped Web Beans should be EJBs.

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

Finally, it's usually obvious when method-level transaction management, method-level security, timers, remote methods or asynchronous methods are needed.

It's usually easy to start with simple Web Bean, and then turn it into an EJB, just by adding an annotation: @Stateless, @Stateful or @Singleton.

1.3.3. Producer methods

A producer method is a method that is called by the Web Bean manager to obtain an instance of the Web Bean when no instance exists in the current context. A producer method lets the application take full control of the instantiation process, instead of leaving instantiation to the Web Bean manager. For example:

public class Generator {

    private Random random = new Random( System.currentTimeMillis() );
    @Produces @Random int next() {
        return random.nextInt(100);


The result of a producer method is injected just like any other Web Bean.

@Random int randomNumber

The method return type and all interfaces it extends/implements directly or indirectly are API types of the producer method. If the return type is a class, all superclasses are also API types.

Some producer methods return objects that require explicit destruction:

@Produces @RequestScoped Connection connect(User user) {
    return createConnection( user.getId(), user.getPassword() );

These producer methods may define matching disposal methods:

void close(@Disposes Connection connection) {

This disposal method is called automatically by the Web Bean manager at the end of the request.

We'll talk much more about producer methods in Chapter 5, Producer methods.

1.3.4. JMS endpoints

Finally, a JMS queue or topic can be a Web Bean. Web Beans relieves the developer from the tedium of managing the lifecycles of all the various JMS objects required to send messages to queues and topics. We'll discuss JMS endpoints in Section 12.4, “JMS endpoints”.