SeamFramework.orgCommunity Documentation

Web Beans: Java Contexts and Dependency Injection

The new standard for dependency injection and contextual state management

I. Using contextual objects
1. Getting started with Web Beans
1.1. Your first Web Bean
1.2. What is a Web Bean?
1.2.1. API types, binding types and dependency injection
1.2.2. Deployment types
1.2.3. Scope
1.2.4. Web Bean names and Unified EL
1.2.5. Interceptor binding types
1.3. What kinds of objects can be Web Beans?
1.3.1. Simple Web Beans
1.3.2. Enterprise Web Beans
1.3.3. Producer methods
1.3.4. JMS endpoints
2. JSF web application example
3. The Web Beans Reference Implementation
3.1. The numberguess example
3.2. The translator example
4. Dependency injection
4.1. Binding annotations
4.1.1. Binding annotations with members
4.1.2. Combinations of binding annnotations
4.1.3. Binding annotations and producer methods
4.1.4. The default binding type
4.2. Deployment types
4.2.1. Enabling deployment types
4.2.2. Deployment type precedence
4.2.3. Example deployment types
4.3. Fixing unsatisfied dependencies
4.4. Client proxies
4.5. Obtaining a Web Bean by programatic lookup
4.6. Lifecycle callbacks, @Resource, @EJB and @PersistenceContext
4.7. The InjectionPoint object
5. Scopes and contexts
5.1. Scope types
5.2. Built-in scopes
5.3. The conversation scope
5.3.1. Conversation demarcation
5.3.2. Conversation propagation
5.3.3. Conversation timeout
5.4. The dependent pseudo-scope
5.4.1. The @New annotation
6. Producer methods
6.1. Scope of a producer method
6.2. Injection into producer methods
6.3. Use of @New with producer methods
II. Developing loosely-coupled code
7. Interceptors
7.1. Interceptor bindings
7.2. Implementing interceptors
7.3. Enabling interceptors
7.4. Interceptor bindings with members
7.5. Multiple interceptor binding annotations
7.6. Interceptor binding type inheritance
7.7. Use of @Interceptors
8. Decorators
8.1. Delegate attributes
8.2. Enabling decorators
9. Events
9.1. Event observers
9.2. Event producers
9.3. Registering observers dynamically
9.4. Event bindings with members
9.5. Multiple event bindings
9.6. Transactional observers
III. Making the most of strong typing
10. Stereotypes
10.1. Default scope and deployment type for a stereotype
10.2. Restricting scope and type with a stereotype
10.3. Interceptor bindings for stereotypes
10.4. Name defaulting with stereotypes
10.5. Standard stereotypes
11. Specialization
11.1. Using specialization
11.2. Advantages of specialization
12. Defining Web Beans using XML
12.1. Declaring Web Bean classes
12.2. Declaring Web Bean metadata
12.3. Declaring Web Bean members
12.4. Declaring inline Web Beans
12.5. Using a schema
IV. Web Beans and the Java EE ecosystem
13. Java EE integration
13.1. Injecting Java EE resources into a Web Bean
13.2. Calling a Web Bean from a Servlet
13.3. Calling a Web Bean from a Message-Driven Bean
13.4. JMS endpoints
13.5. Packaging and deployment
14. Extending Web Beans
14.1. The Manager object
14.2. The Bean class
14.3. The Context interface
15. Next steps
A. Integrating the Web Beans RI into other environments
A.1. The Web Beans RI SPI
A.1.1. Web Bean Discovery
A.1.2. EJB Discovery
A.1.3. JNDI
A.1.4. Resource loading
A.2. The contract with the container

JSR-299 has recently changed it's name from "Web Beans" to "Java Contexts and Dependency Injection". The reference guide still refers to JSR-299 as "Web Beans" and the JSR-299 Reference Implementation as the "Web Beans RI". Other documentation, blogs, forum posts etc. may use the new nomenclature, including the new name for the JSR-299 Reference Implementation - "Web Beans".

The Web Beans (JSR-299) specification defines a set of services for the Java EE environment that makes applications much easier to develop. Web Beans layers an enhanced lifecycle and interaction model over existing Java component types including JavaBeans and Enterprise Java Beans. As a complement to the traditional Java EE programming model, the Web Beans services provide:

Dependency injection, together with contextual lifecycle management, saves the user of an unfamiliar API from having to ask and answer the following questions:

A Web Bean specifies only the type and semantics of other Web Beans it depends upon. It need not be aware of the actual lifecycle, concrete implementation, threading model or other clients of any Web Bean it depends upon. Even better, the concrete implementation, lifecycle and threading model of a Web Bean it depends upon may vary according to the deployment scenario, without affecting any client.

Events, interceptors and decorators enhance the loose-coupling that is inherent in this model:

Most importantly, Web Beans provides all these facilities in a typesafe way. Web Beans never uses string-based identifiers to determine how collaborating objects fit together. And XML, though it remains an option, is rarely used. Instead, Web Beans uses the typing information that is already available in the Java object model, together with a new pattern, called binding annotations, to wire together Web Beans, their dependencies, their interceptors and decorators and their event consumers.

The Web Beans services are general and apply to the following types of components that exist in the Java EE environment:

Web Beans even provides the necessary integration points so that other kinds of components defined by future Java EE specifications or by non-standard frameworks may be cleanly integrated with Web Beans, take advantage of the Web Beans services, and interact with any other kind of Web Bean.

Web Beans was influenced by a number of existing Java frameworks, including Seam, Guice and Spring. However, Web Beans has its own very distinct character: more typesafe than Seam, more stateful and less XML-centric than Spring, more web and enterprise-application capable than Guice.

Most importantly, Web Beans is a JCP standard that integrates cleanly with Java EE, and with any Java SE environment where embeddable EJB Lite is available.

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.

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 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 preexisting 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: 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.

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:

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:

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

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 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 4, Dependency injection.

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?

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:

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.

Let's illustrate these ideas with a full example. We're going to implement user login/logout for an application that uses JSF. First, we'll define a Web Bean to hold the username and password entered during login:

@Named @RequestScoped

public class Credentials {
    private String username;
    private String password;
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }

This Web Bean is bound to the login prompt in the following JSF form:


    <h:panelGrid columns="2" rendered="#{!login.loggedIn}">
        <h:outputLabel for="username">Username:</h:outputLabel>
        <h:inputText id="username" value="#{credentials.username}"/>
        <h:outputLabel for="password">Password:</h:outputLabel>
        <h:inputText id="password" value="#{credentials.password}"/>
    <h:commandButton value="Login" action="#{login.login}" rendered="#{!login.loggedIn}"/>
    <h:commandButton value="Logout" acion="#{login.logout}" rendered="#{login.loggedIn}"/>

The actual work is done by a session scoped Web Bean that maintains information about the currently logged-in user and exposes the User entity to other Web Beans:

@SessionScoped @Named

public class Login {
    @Current Credentials credentials;
    @PersistenceContext EntityManager userDatabase;
    private User user;
    public void login() {
        List<User> results = userDatabase.createQuery(
           "select u from User u where u.username=:username and u.password=:password")
           .setParameter("username", credentials.getUsername())
           .setParameter("password", credentials.getPassword())
        if ( !results.isEmpty() ) {
           user = results.get(0);
    public void logout() {
        user = null;
    public boolean isLoggedIn() {
       return user!=null;
    @Produces @LoggedIn User getCurrentUser() {
        return user;

Of course, @LoggedIn is a binding annotation:


public @interface LoggedIn {}

Now, any other Web Bean can easily inject the current user:

public class DocumentEditor {

    @Current Document document;
    @LoggedIn User currentUser;
    @PersistenceContext EntityManager docDatabase;
    public void save() {

Hopefully, this example gives a flavor of the Web Bean programming model. In the next chapter, we'll explore Web Beans dependency injection in greater depth.

The Web Beans Reference Implementation is being developed at the Seam project. You can download the latest developer release of Web Beans from the the downloads page.

The Web Beans RI comes with a two deployable example applications: webbeans-numberguess, a war example, containing only simple beans, and webbeans-translator an ear example, containing enterprise beans. To run the examples you'll need the following:

  • the latest release of the Web Beans RI,

  • JBoss AS 5.0.0.GA, and

  • Ant 1.7.0.

Currently, the Web Beans RI only runs on JBoss Application Server 5. You'll need to download JBoss AS 5.0.0.GA from, and unzip it. For example:

$ cd /Applications
$ unzip ~/

Next, download the Web Beans RI from, and unzip it. For example

$ cd ~/
$ unzip ~/webbeans-$

Next, we need to tell Web Beans where JBoss is located. Edit jboss-as/ and set the jboss.home property. For example:


As Web Beans is a new piece of software, you need to update JBoss AS to run the Web Beans RI. Future versions of JBoss AS will include these updates, and this step won't be necessary.


Currently, two updates are needed. Firstly, a new deployer, webbeans.deployer is added. This adds supports for Web Bean archives to JBoss AS, and allows the Web Beans RI to query the EJB3 container and discover which EJBs are installed in your application. Secondly, an update to JBoss EJB3 is needed.

To install the update, you'll need Ant 1.7.0 installed, and the ANT_HOME environment variable set. For example:

$ unzip
$ export ANT_HOME=~/apache-ant-1.7.0

Then, you can install the update. The update script will use Maven to download the Web Beans and EJB3 automatically.

$ cd webbeans-$VERSION/jboss-as
$ ant update

Now, you're ready to deploy your first example!


The build scripts for the examples offer a number of targets, these are:

  • ant restart - deploy the example in exploded format

  • ant explode - update an exploded example, without restarting the deployment

  • ant deploy - deploy the example in compressed jar format

  • ant undeploy - remove the example from the server

  • ant clean - clean the example

To deploy the numberguess example:

$ cd examples/numberguess
ant deploy

Start JBoss AS:

$ /Application/jboss-5.0.0.GA/bin/


If you use Windows, use the run.batscript.

Wait for the application to deploy, and enjoy hours of fun at http://localhost:8080/webbeans-numberguess!

The Web Beans RI includes a second simple example that will translate your text into Latin. The numberguess example is a war example, and uses only simple beans; the translator example is an ear example, and includes enterprise beans, packaged in an EJB module. To try it out:

$ cd examples/translator
ant deploy

Wait for the application to deploy, and visit http://localhost:8080/webbeans-translator!

In the numberguess application you get given 10 attempts to guess a number between 1 and 100. After each attempt, you will be told whether you are too high, or too low.

The numberguess example is comprised of a number of Web Beans, configuration files, and Facelet JSF pages, packaged as a war. Let's start with the configuration files.

All the configuration files for this example are located in WEB-INF/, which is stored in WebContent in the source tree. First, we have faces-config.xml, in which we tell JSF to use Facelets:

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"


There is an empty web-beans.xml file, which marks this application as a Web Beans application.

Finally there is web.xml:

Let's take a look at the Facelet view:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns=""

  <ui:composit(1)ion template="template.xhtml">
    <ui:define name="content">
       <h1>Guess a number...</h1>
       <h:form id="NumberGuessMain">
          <div(2) style="color: red">
             <h:messages id="messages" globalOnly="false"/>
             <h:outputText id="Higher" value="Higher!" rendered="#{game.number gt game.guess and game.guess ne 0}"/>
             <h:outputText id="Lower" value="Lower!" rendered="#{game.number lt game.guess and game.guess ne 0}"/>
             I(3)'m thinking of a number between #{game.smallest} and #{game.biggest}.
             You have #{game.remainingGuesses} guesses.
             Your guess: 
             <(4)h:inputText id="inputGuess" 
                          disabled="#{game.number eq game.guess}">
              (5)  <f:validateLongRange maximum="#{game.biggest}" 
            <h(6):commandButton id="GuessButton"  
                             disabled="#{game.number eq game.guess}"/>
            <h:commandButton id="RestartButton" value="Reset" action="#{game.reset}" immediate="true" />

Facelets is a templating language for JSF, here we are wrapping our page in a template which defines the header.


There are a number of messages which can be sent to the user, "Higher!", "Lower!" and "Correct!"


As the user guesses, the range of numbers they can guess gets smaller - this sentance changes to make sure they know what range to guess in.


This input field is bound to a Web Bean, using the value expression.


A range validator is used to make sure the user doesn't accidentally input a number outside of the range in which they can guess - if the validator wasn't here, the user might use up a guess on an out of range number.


And, of course, there must be a way for the user to send their guess to the server. Here we bind to an action method on the Web Bean.

The example exists of 4 classes, the first two of which are binding types. First, there is the @Random binding type, used for injecting a random number:


public @interface Random {}

There is also the @MaxNumber binding type, used for injecting the maximum number that can be injected:


public @interface MaxNumber {}

The Generator class is responsible for creating the random number, via a producer method. It also exposes the maximum possible number via a producer method:


public class Generator {
   private java.util.Random random = new java.util.Random( System.currentTimeMillis() );
   private int maxNumber = 100;
   java.util.Random getRandom()
      return random;
   @Produces @Random int next() { 
      return getRandom().nextInt(maxNumber); 
   @Produces @MaxNumber int getMaxNumber()
      return maxNumber;

You'll notice that the Generator is application scoped; therefore we don't get a different random each time.

The final Web Bean in the application is the session scoped Game.

You'll note that we've used the @Named annotation, so that we can use the bean through EL in the JSF page. Finally, we've used constructor injection to initialize the game with a random number. And of course, we need to tell the player when they've won, so we give feedback with a FacesMessage.

package org.jboss.webbeans.examples.numberguess;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.webbeans.AnnotationLiteral;
import javax.webbeans.Current;
import javax.webbeans.Initializer;
import javax.webbeans.Named;
import javax.webbeans.SessionScoped;
import javax.webbeans.manager.Manager;
public class Game
   private int number;
   private int guess;
   private int smallest;
   private int biggest;
   private int remainingGuesses;
   @Current Manager manager;
   public Game()
   Game(@MaxNumber int maxNumber)
      this.biggest = maxNumber;
   public int getNumber()
      return number;
   public int getGuess()
      return guess;
   public void setGuess(int guess)
      this.guess = guess;
   public int getSmallest()
      return smallest;
   public int getBiggest()
      return biggest;
   public int getRemainingGuesses()
      return remainingGuesses;
   public String check()
      if (guess>number)
         biggest = guess - 1;
      if (guess<number)
         smallest = guess + 1;
      if (guess == number)
         FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!"));
      return null;
   public void reset()
      this.smallest = 0;
      this.guess = 0;
      this.remainingGuesses = 10;
      this.number = manager.getInstanceByType(Integer.class, new AnnotationLiteral<Random>(){});

The translator example will take any sentences you enter, and translate them to Latin.

The translator example is built as an ear, and contains EJBs. As a result, it's structure is more complex than the numberguess example.

First, let's take a look at the ear aggregator, which is located in webbeans-translator-ear module. Maven automatically generates the application.xml for us:


Here we set the context path, which gives us a nice url (http://localhost:8080/webbeans-translator).


If you aren't using Maven to generate these files, you would need META-INF/application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="" 
  <description>Ear Example for the reference implementation of JSR 299: Web Beans</description>

Next, lets look at the war. Just as in the numberguess example, we have a faces-config.xml (to enabled Facelets) and a web.xml (to enable JSF) in WebContent/WEB-INF.

More intersting is the facelet used to translate text. Just as in the numberguess example we have a template, which surrounds the form (ommitted here for brevity):

<h:form id="NumberGuessMain">
      <tr align="center" style="font-weight: bold" >
            Your text
            <h:inputTextarea id="text" value="#{translator.text}" required="true" rows="5" cols="80" />
            <h:outputText value="#{translator.translatedText}" />
      <h:commandButton id="button" value="Translate" action="#{translator.translate}"/>

The user can enter some text in the lefthand textarea, and hit the translate button to see the result to the right.

Finally, let's look at the ejb module, webbeans-translator-ejb. In src/main/resources/META-INF there is just an empty web-beans.xml, used to mark the archive as containing Web Beans.

We've saved the most interesting bit to last, the code! The project has two simple beans, SentenceParser and TextTranslator and two enterprise beans, TranslatorControllerBean and SentenceTranslator. You should be getting quite familiar with what a Web Bean looks like by now, so we'll just highlight the most interesting bits here.

Both SentenceParser and TextTranslator are dependent beans, and TextTranslator uses constructor initialization:

public class TextTranslator { 

   private SentenceParser sentenceParser; 
   private Translator sentenceTranslator; 
   TextTranslator(SentenceParser sentenceParser, Translator sentenceTranslator) 
      this.sentenceParser = sentenceParser; 
      this.sentenceTranslator = sentenceTranslator;

TextTranslator is a stateless bean (with a local business interface), where the magic happens - of course, we couldn't develop a full translator, but we gave it a good go!

Finally, there is UI orientated controller, that collects the text from the user, and dispatches it to the translator. This is a request scoped, named, stateful session bean, which injects the translator.


public class TranslatorControllerBean implements TranslatorController
   @Current TextTranslator translator;

The bean also has getters and setters for all the fields on the page.

As this is a stateful session bean, we have to have a remove method:


   public void remove()

The Web Beans manager will call the remove method for you when the bean is destroyed; in this case at the end of the request.

That concludes our short tour of the Web Beans RI examples. For more on the RI, or to help out, please visit

We need help in all areas - bug fixing, writing new features, writing examples and translating this reference guide.

Web Beans supports three primary mechanisms for dependency injection:

Constructor parameter injection:

public class Checkout {

    private final ShoppingCart cart;
    public Checkout(ShoppingCart cart) {
        this.cart = cart;

Initializer method parameter injection:

public class Checkout {

    private ShoppingCart cart;
    void setShoppingCart(ShoppingCart cart) {
        this.cart = cart;

And direct field injection:

public class Checkout {

    private @Current ShoppingCart cart;

Dependency injection always occurs when the Web Bean instance is first instantiated.

  • First, the Web Bean manager calls the Web Bean constructor, to obtain an instance of the Web Bean.

  • Next, the Web Bean manager initializes the values of all injected fields of the Web Bean.

  • Next, the Web Bean manager calls all initializer methods of Web Bean.

  • Finally, the @PostConstruct method of the Web Bean, if any, is called.

Constructor parameter injection is not supported for EJB beans, since the EJB is instantiated by the EJB container, not the Web Bean manager.

Parameters of constructors and initializer methods need not be explicitly annotated when the default binding type @Current applies. Injected fields, however, must specify a binding type, even when the default binding type applies. If the field does not specify a binding type, it will not be injected.

Producer methods also support parameter injection:

@Produces Checkout createCheckout(ShoppingCart cart) {

    return new Checkout(cart);

Finally, observer methods (which we'll meet in Chapter 9, Events), disposal methods and destructor methods all support parameter injection.

The Web Beans specification defines a procedure, called the typesafe resolution algorithm, that the Web Bean manager follows when identifying the Web Bean to inject to an injection point. This algorithm looks complex at first, but once you understand it, it's really quite intuitive. Typesafe resolution is performed at system initialization time, which means that the manager will inform the user immediately if a Web Bean's dependencies cannot be satisfied, by throwing a UnsatisfiedDependencyException or AmbiguousDependencyException.

The purpose of this algorithm is to allow multiple Web Beans to implement the same API type and either:

  • allow the client to select which implementation it requires using binding annotations,

  • allow the application deployer to select which implementation is appropriate for a particular deployment, without changes to the client, by enabling or disabling deployment types, or

  • allow one implementation of an API to override another implementation of the same API at deployment time, without changes to the client, using deployment type precedence.

Let's explore how the Web Beans manager determines a Web Bean to be injected.

If we have more than one Web Bean that implements a particular API type, the injection point can specify exactly which Web Bean should be injected using a binding annotation. For example, there might be two implementations of PaymentProcessor:


public class ChequePaymentProcessor implements PaymentProcessor {
    public void process(Payment payment) { ... }

public class CreditCardPaymentProcessor implements PaymentProcessor {
    public void process(Payment payment) { ... }

Where @PayByCheque and @PayByCreditCard are binding annotations:


public @interface PayByCheque {}

public @interface PayByCreditCard {}

A client Web Bean developer uses the binding annotation to specify exactly which Web Bean should be injected.

Using field injection:

@PayByCheque PaymentProcessor chequePaymentProcessor;

@PayByCreditCard PaymentProcessor creditCardPaymentProcessor;

Using initializer method injection:


public void setPaymentProcessors(@PayByCheque PaymentProcessor chequePaymentProcessor, 
                                 @PayByCreditCard PaymentProcessor creditCardPaymentProcessor) {
   this.chequePaymentProcessor = chequePaymentProcessor;
   this.creditCardPaymentProcessor = creditCardPaymentProcessor;

Or using constructor injection:


public Checkout(@PayByCheque PaymentProcessor chequePaymentProcessor, 
                @PayByCreditCard PaymentProcessor creditCardPaymentProcessor) {
   this.chequePaymentProcessor = chequePaymentProcessor;
   this.creditCardPaymentProcessor = creditCardPaymentProcessor;

All Web Beans have a deployment type. Each deployment type identifies a set of Web Beans that should be conditionally installed in some deployments of the system.

For example, we could define a deployment type named @Mock, which would identify Web Beans that should only be installed when the system executes inside an integration testing environment:


  @Target({TYPE, METHOD})
  public @interface Mock {}

Suppose we had some Web Bean that interacted with an external system to process payments:

public class ExternalPaymentProcessor {

    public void process(Payment p) {

Since this Web Bean does not explicitly specify a deployment type, it has the default deployment type @Production.

For integration or unit testing, the external system is slow or unavailable. So we would create a mock object:


public class MockPaymentProcessor implements PaymentProcessor {
    public void process(Payment p) {

But how does the Web Bean manager determine which implementation to use in a particular deployment?

If you've been paying attention, you're probably wondering how the Web Bean manager decides which implementation — ExternalPaymentProcessor or MockPaymentProcessor — to choose. Consider what happens when the manager encounters this injection point:

@Current PaymentProcessor paymentProcessor

There are now two Web Beans which satisfy the PaymentProcessor contract. Of course, we can't use a binding annotation to disambiguate, since binding annotations are hard-coded into the source at the injection point, and we want the manager to be able to decide at deployment time!

The solution to this problem is that each deployment type has a different precedence. The precedence of the deployment types is determined by the order in which they appear in web-beans.xml. In our example, @Mock appears later than @Production so it has a higher precedence.

Whenever the manager discovers that more than one Web Bean could satisfy the contract (API type plus binding annotations) specified by an injection point, it considers the relative precedence of the Web Beans. If one has a higher precedence than the others, it chooses the higher precedence Web Bean to inject. So, in our example, the Web Bean manager will inject MockPaymentProcessor when executing in our integration testing environment (which is exactly what we want).

It's interesting to compare this facility to today's popular manager architectures. Various "lightweight" containers also allow conditional deployment of classes that exist in the classpath, but the classes that are to be deployed must be explicity, individually, listed in configuration code or in some XML configuration file. Web Beans does support Web Bean definition and configuration via XML, but in the common case where no complex configuration is required, deployment types allow a whole set of Web Beans to be enabled with a single line of XML. Meanwhile, a developer browsing the code can easily identify what deployment scenarios the Web Bean will be used in.

Clients of an injected Web Bean do not usually hold a direct reference to a Web Bean instance.

Imagine that a Web Bean bound to the application scope held a direct reference to a Web Bean bound to the request scope. The application scoped Web Bean is shared between many different requests. However, each request should see a different instance of the request scoped Web bean!

Now imagine that a Web Bean bound to the session scope held a direct reference to a Web Bean bound to the application scope. From time to time, the session context is serialized to disk in order to use memory more efficiently. However, the application scoped Web Bean instance should not be serialized along with the session scoped Web Bean!

Therefore, unless a Web Bean has the default scope @Dependent, the Web Bean manager must indirect all injected references to the Web Bean through a proxy object. This client proxy is responsible for ensuring that the Web Bean instance that receives a method invocation is the instance that is associated with the current context. The client proxy also allows Web Beans bound to contexts such as the session context to be serialized to disk without recursively serializing other injected Web Beans.

Unfortunately, due to limitations of the Java language, some Java types cannot be proxied by the Web Bean manager. Therefore, the Web Bean manager throws an UnproxyableDependencyException if the type of an injection point cannot be proxied.

The following Java types cannot be proxied by the Web Bean manager:

It's usually very easy to fix an UnproxyableDependencyException. Simply add a constructor with no parameters to the injected class, introduce an interface, or change the scope of the injected Web Bean to @Dependent.

There are certain kinds of dependent objects — Web Beans with scope @Dependent — that need to know something about the object or injection point into which they are injected in order to be able to do what they do. For example:

A Web Bean with scope @Dependent may inject an instance of InjectionPoint and access metadata relating to the injection point to which it belongs.

Let's look at an example. The following code is verbose, and vulnerable to refactoring problems:

Logger log = Logger.getLogger(MyClass.class.getName());

This clever little producer method lets you inject a JDK Logger without explicitly specifying the log category:

class LogFactory {

   @Produces Logger createLogger(InjectionPoint injectionPoint) { 
      return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); 

We can now write:

@Current Logger log;

Not convinced? Then here's a second example. To inject HTTP parameters, we need to define a binding type:


public @interface HttpParam {
   @NonBinding public String value();

We would use this binding type at injection points as follows:

@HttpParam("username") String username;

@HttpParam("password") String password;

The following producer method does the work:

class HttpParams

   @Produces @HttpParam("")
   String getParamValue(ServletRequest request, InjectionPoint ip) {
      return request.getParameter(ip.getAnnotation(HttpParam.class).value());

(Note that the value() member of the HttpParam annotation is ignored by the Web Bean manager since it is annotated @NonBinding.)

The Web Bean manager provides a built-in Web Bean that implements the InjectionPoint interface:

public interface InjectionPoint { 

   public Object getInstance(); 
   public Bean<?> getBean(); 
   public Member getMember(): 
   public <extends Annotation> T getAnnotation(Class<T> annotation); 
   public Set<extends Annotation> getAnnotations(); 

So far, we've seen a few examples of scope type annotations. The scope of a Web Bean determines the lifecycle of instances of the Web Bean. The scope also determines which clients refer to which instances of the Web Bean. According to the Web Beans specification, a scope determines:

  • When a new instance of any Web Bean with that scope is created

  • When an existing instance of any Web Bean with that scope is destroyed

  • Which injected references refer to any instance of a Web Bean with that scope

For example, if we have a session scoped Web Bean, CurrentUser, all Web Beans that are called in the context of the same HttpSession will see the same instance of CurrentUser. This instance will be automatically created the first time a CurrentUser is needed in that session, and automatically destroyed when the session ends.

The Web Beans conversation scope is a bit like the traditional session scope in that it holds state associated with a user of the system, and spans multiple requests to the server. However, unlike the session scope, the conversation scope:

A conversation represents a task, a unit of work from the point of view of the user. The conversation context holds state associated with what the user is currently working on. If the user is doing multiple things at the same time, there are multiple conversations.

The conversation context is active during any JSF request. However, most conversations are destroyed at the end of the request. If a conversation should hold state across multiple requests, it must be explicitly promoted to a long-running conversation.

Web Beans provides a built-in Web Bean for controlling the lifecyle of conversations in a JSF application. This Web Bean may be obtained by injection:

@Current Conversation conversation;

To promote the conversation associated with the current request to a long-running conversation, call the begin() method from application code. To schedule the current long-running conversation context for destruction at the end of the current request, call end().

In the following example, a conversation-scoped Web Bean controls the conversation with which it is associated:

@ConversationScoped @Stateful

public class OrderBuilder {
    private Order order;
    private @Current Conversation conversation;
    private @PersistenceContext(type=EXTENDED) EntityManager em;
    @Produces public Order getOrder() {
        return order;
    public Order createOrder() {
        order = new Order();
        return order;
    public void addLineItem(Product product, int quantity) {
        order.add( new LineItem(product, quantity) );
    public void saveOrder(Order order) {
    public void destroy() {}

This Web Bean is able to control its own lifecycle through use of the Conversation API. But some other Web Beans have a lifecycle which depends completely upon another object.

In addition to the four built-in scopes, Web Beans features the so-called dependent pseudo-scope. This is the default scope for a Web Bean which does not explicitly declare a scope type.

For example, this Web Bean has the scope type @Dependent:

public class Calculator { ... }

When an injection point of a Web Bean resolves to a dependent Web Bean, a new instance of the dependent Web Bean is created every time the first Web Bean is instantiated. Instances of dependent Web Beans are never shared between different Web Beans or different injection points. They are dependent objects of some other Web Bean instance.

Dependent Web Bean instances are destroyed when the instance they depend upon is destroyed.

Web Beans makes it easy to obtain a dependent instance of a Java class or EJB bean, even if the class or EJB bean is already declared as a Web Bean with some other scope type.

Producer methods let us overcome certain limitations that arise when the Web Bean manager, instead of the application, is responsible for instantiating objects. They're also the easiest way to integrate objects which are not Web Beans into the Web Beans environment. (We'll meet a second approach in Chapter 12, Defining Web Beans using XML.)

According to the spec:

A Web Beans producer method acts as a source of objects to be injected, where:

  • the objects to be injected are not required to be instances of Web Beans,

  • the concrete type of the objects to be injected may vary at runtime or

  • the objects require some custom initialization that is not performed by the Web Bean constructor

For example, producer methods let us:

  • expose a JPA entity as a Web Bean,

  • expose any JDK class as a Web Bean,

  • define multiple Web Beans, with different scopes or initialization, for the same implementation class, or

  • vary the implementation of an API type at runtime.

In particular, producer methods let us use runtime polymorphism with Web Beans. As we've seen, deployment types are a powerful solution to the problem of deployment-time polymorphism. But once the system is deployed, the Web Bean implementation is fixed. A producer method has no such limitation:


public class Preferences {
    private PaymentStrategyType paymentStrategy;
    @Produces @Preferred 
    public PaymentStrategy getPaymentStrategy() {
        switch (paymentStrategy) {
            case CREDIT_CARD: return new CreditCardPaymentStrategy();
            case CHEQUE: return new ChequePaymentStrategy();
            case PAYPAL: return new PayPalPaymentStrategy();
            default: return null;

Consider an injection point:

@Preferred PaymentStrategy paymentStrat;

This injection point has the same type and binding annotations as the producer method, so it resolves to the producer method using the usual Web Beans injection rules. The producer method will be called by the Web Bean manager to obtain an instance to service this injection point.


There's one potential problem with the code above. The implementations of CreditCardPaymentStrategy are instantiated using the Java new operator. Objects instantiated directly by the application can't take advantage of dependency injection and don't have interceptors.

If this isn't what we want we can use dependency injection into the producer method to obtain Web Bean instances:

@Produces @Preferred @SessionScoped

public PaymentStrategy getPaymentStrategy(CreditCardPaymentStrategy ccps,
                                          ChequePaymentStrategy cps,
                                          PayPalPaymentStrategy ppps) {
    switch (paymentStrategy) {
        case CREDIT_CARD: return ccps;
        case CHEQUE: return cps;
        case PAYPAL: return ppps;
        default: return null;

Wait, what if CreditCardPaymentStrategy is a request scoped Web Bean? Then the producer method has the effect of "promoting" the current request scoped instance into session scope. This is almost certainly a bug! The request scoped object will be destroyed by the Web Bean manager before the session ends, but the reference to the object will be left "hanging" in the session scope. This error will not be detected by the Web Bean manager, so please take extra care when returning Web Bean instances from producer methods!

There's at least three ways we could go about fixing this bug. We could change the scope of the CreditCardPaymentStrategy implementation, but this would affect other clients of that Web Bean. A better option would be to change the scope of the producer method to @Dependent or @RequestScoped.

But a more common solution is to use the special @New binding annotation.

The first major theme of Web Beans is loose coupling. We've already seen three means of achieving loose coupling:

These techniques serve to enable loose coupling of client and server. The client is no longer tightly bound to an implementation of an API, nor is it required to manage the lifecycle of the server object. This approach lets stateful objects interact as if they were services.

Loose coupling makes a system more dynamic. The system can respond to change in a well-defined manner. In the past, frameworks that attempted to provide the facilities listed above invariably did it by sacrificing type safety. Web Beans is the first technology that achieves this level of loose coupling in a typesafe way.

Web Beans provides three extra important facilities that further the goal of loose coupling:

Let's explore interceptors first.

Web Beans re-uses the basic interceptor architecture of EJB 3.0, extending the functionality in two directions:

  • Any Web Bean may have interceptors, not just session beans.

  • Web Beans features a more sophisticated annotation-based approach to binding interceptors to Web Beans.

The EJB specification defines two kinds of interception points:

  • business method interception, and

  • lifecycle callback interception.

A business method interceptor applies to invocations of methods of the Web Bean by clients of the Web Bean:

public class TransactionInterceptor {

    @AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }

A lifecycle callback interceptor applies to invocations of lifecycle callbacks by the container:

public class DependencyInjectionInterceptor {

    @PostConstruct public void injectDependencies(InvocationContext ctx) { ... }

An interceptor class may intercept both lifecycle callbacks and business methods.

Interceptors are a powerful way to capture and separate concerns which are orthogonal to the type system. Any interceptor is able to intercept invocations of any Java type. This makes them perfect for solving technical concerns such as transaction management and security. However, by nature, interceptors are unaware of the actual semantics of the events they intercept. Thus, interceptors aren't an appropriate tool for separating business-related concerns.

The reverse is true of decorators. A decorator intercepts invocations only for a certain Java interface, and is therefore aware of all the semantics attached to that interface. This makes decorators a perfect tool for modeling some kinds of business concerns. It also means that a decorator doesn't have the generality of an interceptor. Decorators aren't able to solve technical concerns that cut across many disparate types.

Suppose we have an interface that represents accounts:

public interface Account {

    public BigDecimal getBalance();
    public User getOwner();
    public void withdraw(BigDecimal amount);
    public void deposit(BigDecimal amount);

Several different Web Beans in our system implement the Account interface. However, we have a common legal requirement that, for any kind of account, large transactions must be recorded by the system in a special log. This is a perfect job for a decorator.

A decorator is a simple Web Bean that implements the type it decorates and is annotated @Decorator.


public abstract class LargeTransactionDecorator 
        implements Account {
    @Decorates Account account;
    @PersistenceContext EntityManager em;
    public void withdraw(BigDecimal amount) {
        if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
            em.persist( new LoggedWithdrawl(amount) );
    public void deposit(BigDecimal amount);
        if ( amount.compareTo(LARGE_AMOUNT)>0 ) {
            em.persist( new LoggedDeposit(amount) );

Unlike other simple Web Beans, a decorator may be an abstract class. If there's nothing special the decorator needs to do for a particular method of the decorated interface, you don't need to implement that method.

The Web Beans event notification facility allows Web Beans to interact in a totally decoupled manner. Event producers raise events that are then delivered to event observers by the Web Bean manager. This basic schema might sound like the familiar observer/observable pattern, but there are a couple of twists:

  • not only are event producers decoupled from observers; observers are completely decoupled from producers,

  • observers can specify a combination of "selectors" to narrow the set of event notifications they will receive, and

  • observers can be notified immediately, or can specify that delivery of the event should be delayed until the end of the current transaction

The event producer may obtain an event notifier object by injection:

@Observable Event<Document> documentEvent

The @Observable annotation implicitly defines a Web Bean with scope @Dependent and deployment type @Standard, with an implementation provided by the Web Bean manager.

A producer raises events by calling the fire() method of the Event interface, passing an event object:;

An event object may be an instance of any Java class that has no type variables or wildcard type parameters. The event will be delivered to every observer method that:

The Web Bean manager simply calls all the observer methods, passing the event object as the value of the event parameter. If any observer method throws an exception, the Web Bean manager stops calling observer methods, and the exception is rethrown by the fire() method.

To specify a "selector", the event producer may pass an instance of the event binding type to the fire() method: document, new AnnotationLiteral<Updated>(){} );

The helper class AnnotationLiteral makes it possible to instantiate binding types inline, since this is otherwise difficult to do in Java.

The event will be delivered to every observer method that:

Alternatively, event bindings may be specified by annotating the event notifier injection point:

@Observable @Updated Event<Document> documentUpdatedEvent

Then every event fired via this instance of Event has the annotated event binding. The event will be delivered to every observer method that:

Transactional observers receive their event notifications during the before or after completion phase of the transaction in which the event was raised. For example, the following observer method needs to refresh a query result set that is cached in the application context, but only when transactions that update the Category tree succeed:

public void refreshCategoryTree(@AfterTransactionSuccess @Observes CategoryUpdateEvent event) { ... }

There are three kinds of transactional observers:

Transactional observers are very important in a stateful object model like Web Beans, because state is often held for longer than a single atomic transaction.

Imagine that we have cached a JPA query result set in the application scope:

@ApplicationScoped @Singleton

public class Catalog {
    @PersistenceContext EntityManager em;
    List<Product> products;
    @Produces @Catalog 
    List<Product> getCatalog() {
        if (products==null) {
            products = em.createQuery("select p from Product p where p.deleted = false")
        return products;

From time to time, a Product is created or deleted. When this occurs, we need to refresh the Product catalog. But we should wait until after the transaction completes successfully before performing this refresh!

The Web Bean that creates and deletes Products could raise events, for example:


public class ProductManager {
    @PersistenceContext EntityManager em;
    @Observable Event<Product> productEvent;
    public void delete(Product product) {
        em.delete(product);, new AnnotationLiteral<Deleted>(){});
    public void persist(Product product) {
        em.persist(product);, new AnnotationLiteral<Created>(){});

And now Catalog can observe the events after successful completion of the transaction:

@ApplicationScoped @Singleton

public class Catalog {
    void addProduct(@AfterTransactionSuccess @Observes @Created Product product) {
    void addProduct(@AfterTransactionSuccess @Observes @Deleted Product product) {

The second major theme of Web Beans is strong typing. The information about the dependencies, interceptors and decorators of a Web Bean, and the information about event consumers for an event producer, is contained in typesafe Java constructs that may be validated by the compiler.

You don't see string-based identifiers in Web Beans code, not because the framework is hiding them from you using clever defaulting rules — so-called "configuration by convention" — but because there are simply no strings there to begin with!

The obvious benefit of this approach is that any IDE can provide autocompletion, validation and refactoring without the need for special tooling. But there is a second, less-immediately-obvious, benefit. It turns out that when you start thinking of identifying objects, events or interceptors via annotations instead of names, you have an opportunity to lift the semantic level of your code.

Web Beans encourages you develop annotations that model concepts, for example,

instead of using compound names like

The annotations are reusable. They help describe common qualities of disparate parts of the system. They help us categorize and understand our code. They help us deal with common concerns in a common way. They make our code more literate and more understandable.

Web Beans stereotypes take this idea a step further. A stereotype models a common role in your application architecture. It encapsulates various properties of the role, including scope, interceptor bindings, deployment type, etc, into a single reusable package.

Even Web Beans XML metadata is strongly typed! There's no compiler for XML, so Web Beans takes advantage of XML schemas to validate the Java types and attributes that appear in XML. This approach turns out to make the XML more literate, just like annotations made our Java code more literate.

We're now ready to meet some more advanced features of Web Beans. Bear in mind that these features exist to make our code both easier to validate and more understandable. Most of the time you don't ever really need to use these features, but if you use them wisely, you'll come to appreciate their power.

According to the Web Beans specification:

In many systems, use of architectural patterns produces a set of recurring Web Bean roles. A stereotype allows a framework developer to identify such a role and declare some common metadata for Web Beans with that role in a central place.

A stereotype encapsulates any combination of:

  • a default deployment type,

  • a default scope type,

  • a restriction upon the Web Bean scope,

  • a requirement that the Web Bean implement or extend a certain type, and

  • a set of interceptor binding annotations.

A stereotype may also specify that all Web Beans with the stereotype have defaulted Web Bean names.

A Web Bean may declare zero, one or multiple stereotypes.

A stereotype is a Java annotation type. This stereotype identifies action classes in some MVC framework:


public @interface Action {}

We use the stereotype by applying the annotation to a Web Bean.


public class LoginAction { ... }

We've already seen how the Web Beans dependency injection model lets us override the implementation of an API at deployment time. For example, the following enterprise Web Bean provides an implementation of the API PaymentProcessor in production:

@CreditCard @Stateless

public class CreditCardPaymentProcessor 
        implements PaymentProcessor {

But in our staging environment, we override that implementation of PaymentProcessor with a different Web Bean:

@CreditCard @Stateless @Staging

public class StagingCreditCardPaymentProcessor 
        implements PaymentProcessor {

What we've tried to do with StagingCreditCardPaymentProcessor is to completely replace AsyncPaymentProcessor in a particular deployment of the system. In that deployment, the deployment type @Staging would have a higher priority than the default deployment type @Production, and therefore clients with the following injection point:

@CreditCard PaymentProcessor ccpp

Would receive an instance of StagingCreditCardPaymentProcessor.

Unfortunately, there are several traps we can easily fall into:

  • the higher-priority Web Bean may not implement all the API types of the Web Bean that it attempts to override,

  • the higher-priority Web Bean may not declare all the binding types of the Web Bean that it attempts to override,

  • the higher-priority Web Bean might not have the same name as the Web Bean that it attempts to override, or

  • the Web Bean that it attempts to override might declare a producer method, disposal method or observer method.

In each of these cases, the Web Bean that we tried to override could still be called at runtime. Therefore, overriding is somewhat prone to developer error.

Web Beans provides a special feature, called specialization, that helps the developer avoid these traps. Specialization looks a little esoteric at first, but it's easy to use in practice, and you'll really appreciate the extra security it provides.

So far, we've seen plenty of examples of Web Beans declared using annotations. However, there are a couple of occasions when we can't use annotations to define the Web Bean:

  • when the implementation class comes from some preexisting library, or

  • when there should be multiple Web Beans with the same implementation class.

In either of these cases, Web Beans gives us two options:

  • write a producer method, or

  • declare the Web Bean using XML.

Many frameworks use XML to provide metadata relating to Java classes. However, Web Beans uses a very different approach to specifying the names of Java classes, fields or methods to most other frameworks. Instead of writing class and member names as the string values of XML elements and attributes, Web Beans lets you use the class or member name as the name of the XML element.

The advantage of this approach is that you can write an XML schema that prevents spelling errors in your XML document. It's even possible for a tool to generate the XML schema automatically from the compiled Java code. Or, an integrated development environment could perform the same validation without the need for the explicit intermediate generation step.

The third theme of Web Beans is integration. Web Beans was designed to work in concert with other technologies, helping the application developer fit the other technologies together. Web Beans is an open technology. It forms a part of the Java EE ecosystem, and is itself the foundation for a new ecosystem of portable extensions and integration with existing frameworks and technologies.

We've already seen how Web Beans helps integrate EJB and JSF, allowing EJBs to be bound directly to JSF pages. That's just the beginning. Web Beans offers the same potential to diverse other technologies, such as Business Process Management engines, other Web Frameworks, and third-party component models. The Java EE platform will never be able to standardize all the interesting technologies that are used in the world of Java application development, but Web Beans makes it easier to use the technologies which are not yet part of the platform seamlessly within the Java EE environment.

We're about to see how to take full advantage of the Java EE platform in an application that uses Web Beans. We'll also briefly meet a set of SPIs that are provided to support portable extensions to Web Beans. You might not ever need to use these SPIs directly, but it's nice to know they are there if you need them. Most importantly, you'll take advantage of them indirectly, every time you use a third-party extension.

Web Beans is fully integrated into the Java EE environment. Web Beans have access to Java EE resources and JPA persistence contexts. They may be used in Unified EL expressions in JSF and JSP pages. They may even be injected into some objects, such as Servlets and Message-Driven Beans, which are not Web Beans.

Sending messages using JMS can be quite complex, because of the number of different objects you need to deal with. For queues we have Queue, QueueConnectionFactory, QueueConnection, QueueSession and QueueSender. For topics we have Topic, TopicConnectionFactory, TopicConnection, TopicSession and TopicPublisher. Each of these objects has its own lifecycle and threading model that we need to worry about.

Web Beans takes care of all this for us. All we need to do is declare the queue or topic in web-beans.xml, specifying an associated binding type and connection factory.



Now we can just inject the Queue, QueueConnection, QueueSession or QueueSender for a queue, or the Topic, TopicConnection, TopicSession or TopicPublisher for a topic.

@OrderProcessor QueueSender orderSender;

@OrderProcessor QueueSession orderSession;
public void sendMessage() {
    MapMessage msg = orderSession.createMapMessage();
@StockPrices TopicPublisher pricePublisher;

@StockPrices TopicSession priceSession;
public void sendMessage(String price) {
    pricePublisher.send( priceSession.createTextMessage(price) );

The lifecycle of the injected JMS objects is completely controlled by the Web Bean manager.

Web Beans is intended to be a platform for frameworks, extensions and integration with other technologies. Therefore, Web Beans exposes a set of SPIs for the use of developers of portable extensions to Web Beans. For example, the following kinds of extensions were envisaged by the designers of Web Beans:

  • integration with Business Process Management engines,

  • integration with third-party frameworks such as Spring, Seam, GWT or Wicket, and

  • new technology based upon the Web Beans programming model.

The nerve center for extending Web Beans is the Manager object.

The Manager interface lets us register and obtain Web Beans, interceptors, decorators, observers and contexts programatically.

public interface Manager

   public <T> Set<Bean<T>> resolveByType(Class<T> type, Annotation... bindings);
   public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> apiType,
         Annotation... bindings);
   public <T> T getInstanceByType(Class<T> type, Annotation... bindings);
   public <T> T getInstanceByType(TypeLiteral<T> type,
         Annotation... bindings);
   public Set<Bean<?>> resolveByName(String name);
   public Object getInstanceByName(String name);
   public <T> T getInstance(Bean<T> bean);
   public void fireEvent(Object event, Annotation... bindings);
   public Context getContext(Class<? extends Annotation> scopeType);
   public Manager addContext(Context context);
   public Manager addBean(Bean<?> bean);
   public Manager addInterceptor(Interceptor interceptor);
   public Manager addDecorator(Decorator decorator);
   public <T> Manager addObserver(Observer<T> observer, Class<T> eventType,
         Annotation... bindings);
   public <T> Manager addObserver(Observer<T> observer, TypeLiteral<T> eventType,
         Annotation... bindings);
   public <T> Manager removeObserver(Observer<T> observer, Class<T> eventType,
         Annotation... bindings);
   public <T> Manager removeObserver(Observer<T> observer,
         TypeLiteral<T> eventType, Annotation... bindings);
   public <T> Set<Observer<T>> resolveObservers(T event, Annotation... bindings);
   public List<Interceptor> resolveInterceptors(InterceptionType type,
         Annotation... interceptorBindings);
   public List<Decorator> resolveDecorators(Set<Class<?>> types,
         Annotation... bindings);

We can obtain an instance of Manager via injection:

@Current Manager manager

Currently the Web Beans RI only runs in JBoss AS 5; integrating the RI into other EE environments (for example another application server like Glassfish), into a servlet container (like Tomcat), or with an Embedded EJB3.1 implementation is fairly easy. In this Appendix we will briefly discuss the steps needed.

The Web Beans SPI is located in webbeans-ri-spi module, and packaged as webbeans-ri-spi.jar. Some SPIs are optional, if you need to override the default behavior, others are required.

You can specify the implementation of an SPI either as a system property, or in a properties file META-INF/ All property names are the fully qualified class name of the implemented interface; all property values are the fully qualified class name of the implementation class.

All interfaces in the SPI support the decorator pattern and provide a Forwarding class.

The Web Beans RI also delegates EJB3 bean discovery to the container so that it doesn't have to scan for EJB3 annotations or parse ejb-jar.xml. For each EJB in the application an EJBDescriptor should be discovered:

public interface EjbDiscovery

   public static final String PROPERTY_NAME = EjbDiscovery.class.getName();
    * Gets a descriptor for each EJB in the application
    * @return The bean class to descriptor map 
   public Iterable<EjbDescriptor<?>> discoverEjbs();
public interface EjbDescriptor<T> {

    * Gets the EJB type
    * @return The EJB Bean class
   public Class<T> getType();
    * Gets the local business interfaces of the EJB
    * @return An iterator over the local business interfaces
   public Iterable<BusinessInterfaceDescriptor<?>> getLocalBusinessInterfaces();
    * Gets the remote business interfaces of the EJB
    * @return An iterator over the remote business interfaces
   public Iterable<BusinessInterfaceDescriptor<?>> getRemoteBusinessInterfaces();
    * Get the remove methods of the EJB
    * @return An iterator over the remove methods
   public Iterable<Method> getRemoveMethods();
    * Indicates if the bean is stateless
    * @return True if stateless, false otherwise
   public boolean isStateless();
    * Indicates if the bean is a EJB 3.1 Singleton
    * @return True if the bean is a singleton, false otherwise
   public boolean isSingleton();
    * Indicates if the EJB is stateful
    * @return True if the bean is stateful, false otherwise
   public boolean isStateful();
    * Indicates if the EJB is and MDB
    * @return True if the bean is an MDB, false otherwise
   public boolean isMessageDriven();
    * Gets the EJB name
    * @return The name
   public String getEjbName();

The EjbDescriptor is fairly self-explanatory, and should return the relevant metadata as defined in the EJB specification. In addition to these two interfaces, there is BusinessInterfaceDescriptor which represents a local business interface (encapsulating the interface class and jndi name used to look up an instance of the EJB).

The Web Beans RI can be told to load your implementation of EjbDiscovery using the property org.jboss.webbeans.bootstrap.spi.EjbDiscovery with the fully qualified class name as the value. For example:


If the Web Beans RI is being used in a servlet container, it expects a constructor of the form:

public EjbDiscoveryImpl(ServletContext servletContext) {}

The servlet context can be used to allow your implementation of EjbDiscovery to interact with the container.