Chapter 2. Web Bean definition

A Web Bean is a Java EE component that bears additional metadata defining its lifecycle and interactions with other components according to the Web Beans context model.

Speaking more abstractly, a Web Bean is a source of contextual objects which define application state and/or logic. These objects are called instances of the Web Bean. The Web Bean manager creates and destroys these instances and associates them with the appropriate Web Beans context. Instances of a Web Bean may be injected into other objects (including other Web Bean instances) that execute in the same context, and may be used in EL expressions that are evaluated in the same context.

A Web Bean comprises the following attributes:

In most cases, a Web Bean developer provides the Web Bean implementation by writing business logic in Java code. The developer then defines the remaining attributes by providing additional Web Beans specific metadata, or by allowing them to be defaulted by the Web Bean manager. In certain other cases, for example JMS endpoints defined in Section 3.5, “JMS endpoints”, the developer provides only the Web Beans specific metadata and the Web Bean implementation is provided by the Web Bean manager.

It is sometimes convenient to use XML instead of annotations to define this metadata. The web-beans.xml file format defined in Chapter 9, XML based metadata supports XML declaration of Web Beans.

A Web Bean implementation may be a Java class, an EJB session or singleton bean class, a producer method or a JMS queue or topic, as specified in Chapter 3, Web Bean implementation. The other attributes of the Web Bean are either:

The deployment type, API types and binding types of a Web Bean determine where its instances will be injected by the Web Bean manager.

The Web Bean developer may also create Web Beans interceptors and/or decorators or reuse existing interceptors and/or decorators. The interceptor binding types of a Web Bean determine which interceptors will be applied at runtime. The API types and binding types of a Web Bean determine which decorators will be applied at runtime. Interceptors, decorators and interceptor binding types are specified in Chapter 6, Interceptors and decorators.

A Web Bean implementation may produce or consume events. The Web Beans event notification facility is specified in Chapter 7, Events.

2.1. Functionality provided by the Web Bean manager to the Web Bean

A Web Bean is provided by the Web Bean manager with the following capabilities:

2.2. Web Bean API types

A Web Bean API type defines a client-visible type of the Web Bean. A Web Bean may have multiple API types. For example, the following Web Bean has three API types:

public class BookShop
        extends Business
        implements Shop<Book> { 
    ... 
}

The API types are BookShop, Business and Shop<Book>.

Meanwhile, this EJB has only the local interfaces BookShop and Auditable as API types, since the bean class is not a client-visible type.

@Stateful 
public class BookShopBean 
        extends Business 
        implements BookShop, Auditable { 
    ... 
}

The rules for determining the set of API types for a Web Bean are defined in Chapter 3, Web Bean implementation.

The API types of a Web Bean are used by the resolution algorithms defined in Chapter 4, Lookup, dependency injection and EL resolution.

An API type may be a parameterized type with an actual type parameter. For the purposes of the typesafe resolution algorithm defined in Section 4.9.2, “Typesafe resolution algorithm”, parameterized API types are considered identical by the Web Bean manager only if both the type and the type parameters (if any) are identical. However, API types may not declare a type variable or wildcard.

Aside from this restriction, almost any Java type may be an API type of a Web Bean:

  • An API type may be an interface, a concrete class or an abstract class, and may be declared final or have final methods.

  • An API type may be an array type. Two array types are considered identical only if the element type is identical.

  • An API type may be a primitive types. Primitive types are considered to be identical to their corresponding wrapper types in java.lang.

However, certain additional restrictions are specified in Section 4.4.1, “Unproxyable API types” for Web Beans with a normal scope type, as defined in Section 8.2, “Normal scopes and pseudo-scopes”.

All Web Beans have the API type java.lang.Object.

A client of a Web Bean may typecast its reference to any instance of the Web Bean to any API type of the Web Bean. For example, if our simple Web Bean was injected to the following field:

@Current Shop<Book> bookShop;

Then the following typecast is legal and will not result in an exception:

Business biz = (Business) bookShop;

Likewise, if our EJB was injected to the following field:

@Current BookShop bookShop;

Then the following typecast is legal and will not result in an exception:

Auditable aud = (Auditable) bookShop;

Open issue: currently it is impossible for the client of a stateful session bean to typecast its reference to a different local interface. We need a new API defined by the EJB specification.

2.3. Binding types

For a given API type, there may be multiple Web Beans which implement the type. For example, an application may have two implementations of the interface PaymentProcessor:

class SynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}
class AsynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}

A client that needs a PaymentProcessor that processes payments synchronously needs some way to distinguish between the two different implementations. One approach would be for the client to explicitly specify the class that implements that PaymentProcessor interface. However, this approach creates a hard dependence between client and implementation—exactly what use of the interface was designed to avoid!

A Web Beans binding type represents some client-visible semantic of an API implementation that is satisfied by some implementations of the API (and not by others). For example, we could introduce binding types representing synchronicity and asynchronicity. In Java code, binding types are represented by annotations.

@Synchronous
class SynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}
@Asynchronous
class AsynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}

Finally, binding types are applied to injection points to distinguish which implementation is required by the client. For example, when the Web Bean manager encounters the following injected field, an instance of SynchronousPaymentProcessor will be injected:

@Synchronous PaymentProcessor paymentProcessor;

But in this case, an instance of AsynchronousPaymentProcessor will be injected:

@Asynchronous PaymentProcessor paymentProcessor;

The Web Bean manager inspects the binding annotations and type of the injected attribute to determine the Web Bean instance to be injected, according to the resolution algorithm defined in Chapter 4, Lookup, dependency injection and EL resolution.

Binding types are also used as event selectors by observers of Web Beans events, as defined in Chapter 7, Events, and to bind decorators to Web Beans, as specified in Section 6.3, “Decorators”.

2.3.1. Default binding type

If a Web Bean does not explicitly declare a binding type, the Web Bean has exactly one binding type: javax.webbeans.Current. This is called the default binding type.

The following declarations are equivalent:

@Current
public class Order {}
public class Order {}

The default binding type is also assumed for any injection point that does not explicitly declare a binding type. The following declarations are equivalent:

public class Order {
    public Order(@Current OrderProcessor processor) { ... }
}
public class Order {
    public Order(OrderProcessor processor) { ... }
}

2.3.2. Defining binding types

A binding type is a Java annotation defined as @Target({METHOD, FIELD, PARAMETER, TYPE}) and @Retention(RUNTIME). All binding types must specify the @BindingType meta-annotation.

For example:

@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Synchronous {}
@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Asynchronous {}

A binding annotation may define annotation members.

@BindingType
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface PayBy {
    PaymentMethod value();
}

Binding annotation member values are significant to the typesafe resolution algorithm.

2.3.3. Declaring the binding types of a Web Bean using annotations

A Web Bean's binding types are declared by annotating the implementation class or producer method with the binding types.

@LDAP 
class LdapAuthenticator 
        implements Authenticator {
    ...
}
public class Shop {

   @Produces @All
   public List<Product> getAllProducts() { ... }

   @Produces @WishList
   public List<Product> getWishList() { ..... }
   
   @Produces @ShoppingCart
   public List<Product> getShoppingCart() { ..... }

}

Any Web Bean may declare multiple binding types.

@Synchronous @Reliable
class SynchronousReliablePaymentProcessor 
        implements PaymentProcessor {
    ...
}

If no binding type is explicitly specified, the default binding type is assumed.

2.3.4. Declaring the binding types of a Web Bean using XML

If a Web Bean is declared in web-beans.xml, binding types may be specified using the binding type names:

<myapp:SynchronousPaymentProcessor>
    <myapp:Synchronous/>
    <myapp:Reliable/>
</myapp:SynchronousPaymentProcessor>

If any binding type is specified in XML, the binding annotations appearing on the implementation class or producer method are ignored and all binding types must be explicitly specified in XML.

Otherwise, if no binding types are specified in XML, the binding annotations that appear on the implementation class or producer method are used. If no binding annotations appear on the implementation class or producer method, the default binding type is used.

2.3.5. Using binding annotations on injected fields

Binding annotations are applied to injected fields (see Section 3.6, “Injected fields”) to determine the Web Bean that is injected, according to the typesafe resolution algorithm defined in Section 4.9.2, “Typesafe resolution algorithm”.

@LDAP Authenticator authenticator;

A Web Bean may only be injected to an injection point if it has all the binding types of the injection point.

@Synchronous @Reliable PaymentProcessor paymentProcessor;

For the case of producer methods, the binding annotation help determine exactly which producer method is called:

@All List<Product> catalog;
@WishList List<Product> wishList;
@ShoppingCart List<Product> cart;

For a Web Bean defined in XML, the binding types of a field may be specified using XML:

<myapp:paymentProcessor>
    <myapp:Asynchronous/>
    <myapp:Reliable/>
</myapp:paymentProcessor>

When the binding types of a field are specified using XML, any binding type annotations of the field are ignored.

2.3.6. Using binding annotations on method or constructor parameters

Binding annotations may be applied to parameters of producer methods, initializer methods, disposal methods, Web Bean remove methods or Web Bean constructors (see Chapter 3, Web Bean implementation) to determine the Web Bean instance that is passed when the method is called by the Web Bean manager. The Web Bean manager uses the typesafe resolution algorithm defined in Section 4.9.2, “Typesafe resolution algorithm” to determine values for these parameters.

For example, when the Web Bean manager encounters the following producer method, an instance of SynchronousPaymentProcessor will be passed to the first parameter and an instance of AsynchronousPaymentProcessor will be passed to the second parameter:

@Produces
PaymentProcessor getPaymentProcessor(@Synchronous PaymentProcessor sync, 
                                     @Asynchronous PaymentProcessor async) {
    return isSynchronous() ? sync : async;
}

For a Web Bean defined in XML, the binding types of a method parameter may be specified using XML:

<myapp:getPaymentProcessor>
    <Produces/>
    <myapp:PaymentProcessor>
        <myapp:Synchronous/>
    </myapp:PaymentProcessor>
    <myapp:PaymentProcessor>
        <myapp:Asynchronous/>
    </myapp:PaymentProcessor>
</myapp:getPaymentProcessor>

When the binding types of a parameter are specified using XML, any binding type annotations of the parameter are ignored.

2.4. Web Bean scopes

Unlike JSF managed beans, Java EE components such as Servlets, EJBs and JavaBeans do not have a well-defined scope. These components are either:

  • singletons, such as EJB singleton beans, whose state is shared between all clients,

  • stateless objects, such as Servlets and stateless session beans, which do not contain client-visible state, or

  • objects that must be explictly created and destroyed by their client, such as JavaBeans and stateful session beans, whose state is shared by explicit reference passing between clients.

Scoped objects, by contrast, exist in a well-defined context:

  • they may be automatically created when needed and then automatically destroyed when the context in which they were created ends, and

  • their state is automatically shared by clients that execute in the same context.

All Web Beans have a scope. The scope of a Web Bean determines the lifecycle of its instances, and which instances of the Web Bean are visible to instances of other Web Beans, as defined in Chapter 8, Scopes and contexts. A scope type is represented by an annotation type.

For example, an object that represents the current user is represented by a session scoped object:

@Produces @SessionScoped User getCurrentUser() { ... }

An object that represents an order is represented by a conversation scoped object:

@ConversationScoped 
public class Order {
   ... 
}

A list that contains the results of a search screen might be represented by a request scoped object:

@Produces @RequestScoped @Named("orders") 
List<Order> getOrderSearchResults() { ... }

The set of scope types is extensible.

2.4.1. Built-in scope types

There are several standard scope types defined by Web Beans. The @RequestScoped, @ApplicationScoped and @SessionScoped annotations defined in Section 8.5, “Context management for built-in scopes” represent the standard scopes defined by the Java Servlets specification. The @ConversationScoped annotation represents the Web Beans conversation scope defined in Section 8.5.4, “Conversation context lifecycle”. In addition, there is the @Dependent pseudo-scope for dependent objects, as defined in Section 8.3, “Dependent pseudo-scope”.

2.4.2. Defining new scope types

A Web Beans scope type is a Java annotation defined as @Target({TYPE, METHOD}) and @Retention(RUNTIME). All scope types must also specify the @ScopeType meta-annotation.

For example, the following annotation declares a "business process scope":

@ScopeType
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface BusinessProcessScoped {}

An application or third-party framework might provide a context implementation for this custom scope (see Section 8.6, “Context management for custom scopes”).

2.4.3. Declaring the Web Bean scope using annotations

The Web Bean's scope is defined by annotating the implementation class or producer method with a scope type.

A Web Bean implementation class or producer method may specify at most one scope type annotation. If an implementation class or producer method specifies multiple scope type annotations, a DefinitionException is thrown by the Web Bean manager at startup time.

The following examples demonstrate the use of built-in scope types:

@RequestScoped
public class ProductList implements DataModel { ... }
public class Shop {

   @Produces @SessionScoped @WishList
   public List<Product> getWishList() { ..... }

   @Produces @ConversationScoped @ShoppingCart
   public List<Product> getShoppingCart() { ..... }

}

Likewise, a Web Bean with the custom business process scope may be declared by annotating it with the @BusinessProcessScoped annotation:

@BusinessProcessScoped
public class Order {
    ...
}

Alternatively, a scope type may be specified using a stereotype annotation, as defined in Section 2.7.2, “Declaring the stereotypes for a Web Bean using annotations”.

2.4.4. Declaring the Web Bean scope using XML

If the Web Bean is declared in web-beans.xml, the scope may be specified using the scope annotation type name:

<myapp:ProductList>
    <RequestScoped/>
</myapp:ProductList>

If more than one scope type is specified in XML, a DefinitionException is thrown by the Web Bean manager at initialization time.

If an implementation class or producer method with a scope type annotation is specified and if no scope type is explicitly specified in XML, the scope defined by the scope type annotation is used.

Alternatively, a scope type may be specified using a stereotype declared in XML, as defined in Section 2.7.3, “Declaring the stereotypes for a Web Bean using XML”.

2.4.5. Default scope

When no scope is explicitly declared by annotating the implementation class or producer method, or by using XML, the scope of a Web Bean is defaulted.

The default scope for a Web Bean which does not explicitly declare a scope depends upon its declared stereotypes:

  • If the Web Bean does not declare any stereotype with a declared default scope, the default scope for the Web Bean is @Dependent.

  • If all stereotypes declared by the Web Bean that have some declared default scope have the same default scope, then that scope is the default scope for the Web Bean.

  • If there are two different stereotypes declared by the Web Bean that declare different default scopes, then there is no default scope and the Web Bean must explicitly declare a scope. If it does not explicitly declare a scope, a DefinitionException is thrown by the Web Bean manager at initialization time.

If a Web Bean explicitly declares a scope, any default scopes declared by stereotypes are ignored.

2.5. Deployment types

In many applications, there are various implementations of a particular API, and the implementation used at runtime varies between different deployments of the system. Web Beans allows the developer to associate a particular implementation of an API with a certain deployment scenario.

A Web Beans deployment type represents a deployment scenario. Web Beans may be classified by deployment type, and thereby associated with various deployment scenarios.

Deployment types allow the Web Bean manager to identify which Web Beans should be enabled for use in a particular deployment of the system. The deployment type also determines the precedence of a Web Bean, used by the resolution algorithms specified in Chapter 4, Lookup, dependency injection and EL resolution.

The set of deployment types is extensible.

2.5.1. Built-in deployment types

There are two standard deployment types defined by Web Beans: @Production and @Standard.

All standard Web Beans defined by this specification, and provided by the Web Bean manager, are defined using the @Standard deployment type. For example, the Conversation object defined in Section 8.5.4, “Conversation context lifecycle” and the Manager object defined in Section 4.8, “The Manager object” have this deployment type. No Web Bean may be declared with the @Standard deployment type unless explicitly required by this specification.

Application Web Beans may be defined using the @Production deployment type.

2.5.2. Defining new deployment types

A Web Beans deployment type is a Java annotation defined as @Target({TYPE, METHOD}) and @Retention(RUNTIME). All deployment types must also specify the @DeploymentType meta-annotation.

Applications and third-party frameworks may define their own deployment types. For example, the following deployment type might identify Web Beans which are used only at a particular site at which the application is deployed:

@DeploymentType
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Australian {}

This deployment type might be used by a third-party framework that extends Web Beans:

@DeploymentType
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface DaoFramework {}

This deployment type might be used to define mock objects for integration testing:

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

2.5.3. Declaring the deployment type of a Web Bean using annotations

The deployment type of the Web Bean is declared by annotating the implementation class or producer method.

An implementation class or producer method may specify at most one deployment type. If multiple deployment type annotations are specified, a DefinitionException is thrown by the Web Bean manager at initialization time.

Open issue: is this too restrictive? We could allow multiple deployment types to be specified, and ignore all but the highest-precedence enabled deployment type.

This Web Bean has the deployment type @Production:

@Production
public class Order {}

This Web Bean has the deployment type @Mock:

@Mock
public class MockOrder extends Order {}

By default, if no deployment type annotation is explicitly specified, a producer method inherits the deployment type of the Web Bean in which it is defined.

This producer method has the deployment type @Production:

@Production
public class Login {

   @Produces
   public User getUser() { ... }

}

This producer method has the deployment type @Australian:

@Production
public class TaxPolicies {

   @Produces @Australian
   public TaxPolicy getAustralianTaxPolicy() { ... }

}

Alternatively, a deployment type may be specified using a stereotype annotation, as defined in Section 2.7.2, “Declaring the stereotypes for a Web Bean using annotations”.

2.5.4. Declaring the deployment type of a Web Bean using XML

When a Web Bean is declared in web-beans.xml, the deployment type may be specified using a tag with the annotation type name:

<myapp:AustralianTaxPolicy>
    <deployment:Australian/>
</myapp:AustralianTaxPolicy>

If more than one deployment type is specified in XML, a DefinitionException is thrown by the Web Bean manager at initialization time.

If an implementation class or producer method with a deployment type annotation is specified and if no deployment type is explicitly specified in XML, the deployment type defined by the deployment type annotation is used.

Alternatively, a deployment type may be specified using a stereotype declared in XML, as defined in Section 2.7.3, “Declaring the stereotypes for a Web Bean using XML”.

2.5.5. Default deployment type

When no deployment type is explicitly declared by annotating the implementation class or producer method, or by use of XML, the deployment type is defaulted.

The default deployment type for a Web Bean which does not explicitly declare a deployment type depends upon its declared stereotypes:

  • If a Web Bean does not declare any stereotype with a declared default deployment type, then the default deployment type is @Production.

  • Otherwise, the default deployment type for the Web Bean is the highest-precedence default deployment type declared by any stereotype declared by the Web Bean.

Thus, the following declarations are equivalent:

@Production
public class Order {}
public class Order {}

If a Web Bean explicitly declares a deployment type, any default deployment type declared by stereotypes are ignored.

2.5.6. Enabled deployment types

In a particular deployment, only some deployment types are enabled. Web Beans declared with a deployment type that is not enabled are not available to the resolution algorithms defined in Chapter 4, Lookup, dependency injection and EL resolution.

The Web Bean manager inspects the deployment type of each Web Bean that exists in a particular deployment (see Section 10.1, “Web Bean discovery”) to determine whether the Web Bean is enabled in this deployment. If the deployment type is enabled, an instance of the Web Bean may be obtained by lookup, injection or EL resolution. Otherwise, the Web Bean is never instantiated by the Web Bean manager.

By default, only the built-in deployment types are enabled. To enable a custom deployment type, a <Deploy> element must be included in a web-beans.xml file and the deployment type must be declared using the annotation type name.

<WebBeans>
    <Deploy>
        <Standard/>
        <Production/>
        <myfwk:DaoFramework/>
        <deployment:Australian/>
        <myfwk:Mock/>
    </Deploy>
</WebBeans>

If a <Deploy> element is specified, only the explicitly declared deployment types are enabled. The @Standard deployment type must be declared. If the @Standard deployment type is not declared, a DeploymentException is thrown by the Web Bean manager at initialization time.

If no <Deploy> element is specified in any web-beans.xml file, only the @Standard and @Production deployment types are enabled.

If the <Deploy> element is specified in more than one web-beans.xml document, a DeploymentException is thrown by the Web Bean manager at initialization time.

2.5.7. Deployment type precedence

In a particular deployment, all enabled deployment types are strongly ordered in terms of precedence. The precedence of a deployment type is used by the resolution algorithms defined in Chapter 4, Lookup, dependency injection and EL resolution.

If a <Deploy> element is specified, the order of the deployment type declarations determines the deployment type precedence. Deployment types which appear later in this list have a higher precedence than deployment types which appear earlier. The @Standard deployment type must appear first and always has the lowest precedence of any deployment type.

If no <Deploy> element is specified, the @Production deployment type has a higher precedence than the @Standard deployment type.

2.6. Web Bean names

A Web Bean may have a Web Bean name. A Web Bean with a name may be referred to by its Web Bean name in Unified EL expressions. A valid Web Bean name is a period-separated list of valid EL identifiers.

There is no relationship between the Web Bean name of an EJB bean and the EJB name of the bean.

In certain circumstances, multiple Web Beans may share the same name.

Names are used by the EL name resolution algorithm defined in Section 4.9.2, “Typesafe resolution algorithm”. This allows a Web Bean to be used directly in a JSP or JSF page.

For example, a Web Bean with the name products could be used like this:

<h:outputText value="#{products.total}"/>

JMS endpoints do not have names.

2.6.1. Declaring the Web Bean name using annotations

To specify the name of a Web Bean, the @Named annotation is applied to the implementation class or producer method. This Web Bean is named products:

@Named("products")
public class ProductList implements DataModel { ... }

If the @Named annotation does not specify the value member, the default name is assumed.

2.6.2. Declaring the Web Bean name using XML

If the Web Bean is declared in web-beans.xml, the name may be specified using <Named>:

<myapp:ProductList>
    <Named>products</Named>
</myapp:ProductList>

If the <Named> element is empty, the default name is assumed.

If an implementation class or producer method with a @Named annotation is specified, and if no <Named> element is explicitly specified, the name specified by the @Named annotation is used. If the @Named annotation does not specify the value member, the default name is assumed.

If a <Named> element is specified, the @Named annotation is ignored.

2.6.3. Default Web Bean names

In the following circumstances, a default name must be assigned by the Web Bean manager:

  • An implementation class or producer method of a Web Bean defined using annotations declares a @Named annotation and no name is explicitly specified by the value member.

  • An empty <Named> element is specified by a Web Bean defined in XML.

  • No <Named> element is specified by a Web Bean defined in XML, but the implementation class or producer method declares a @Named annotation and no name is explicitly specified by the value member.

  • A Web Bean declares a stereotype that declares an empty @Named annotation, and the Web Bean does not explicitly specify a name.

The default name for a Web Bean depends upon the Web Bean implementation. The rules for determining the default name for a Web Bean are defined in Chapter 3, Web Bean implementation.

2.6.4. Web Beans with no name

If neither <Named> nor @Named is specified, by the Web Bean or its stereotypes, a Web Bean has no name.

2.7. Stereotypes

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.

Open issue: should stereotype "inheritance" be supported?

2.7.1. Defining new stereotypes

A Web Beans stereotype is a Java annotation defined as @Target({TYPE, METHOD}), @Target(METHOD) or @Target(TYPE) and @Retention(RUNTIME). All stereotypes must also specify the @Stereotype meta-annotation.

A stereotype may declare at most one scope type. If a stereotype declares more than one scope type, a DefinitionException is thrown by the Web Bean manager at initialization time.

A stereotype may declare at most one deployment type. If a stereotype declares more than one deployment type, a DefinitionException is thrown by the Web Bean manager at initialization time.

A stereotype may declare an empty @Named annotation. If a stereotype declares a non-empty @Named annotation, a DefinitionException is thrown by the Web Bean manager at initialization time.

A stereotype may declare zero, one or multiple interceptor binding types, as defined in Section 6.2.4, “Interceptor bindings”.

A stereotype may not declare any binding type annotation. If a stereotype declares a binding type annotation, a DefinitionException is thrown by the Web Bean manager at initialization time.

For example, the following stereotype might be used to identify action classes in a web application:

@RequestScoped
@Production
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

Then actions would have scope @RequestScoped and deployment type @Production unless the scope or deployment type explicitly specified by the Web Bean.

We may specify interceptor bindings that apply to all actions:

@RequestScoped
@Secure
@Transactional
@Production
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

We may specify that every Web Bean with the stereotype has a defaulted name when a name is not explicitly specified by the Web Bean:

@RequestScoped
@Secure
@Transactional
@Named
@Production
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

If all actions are request scoped, we can make this restriction explicit:

@RequestScoped
@Secure
@Transactional
@Production
@Stereotype(supportedScopes=RequestScoped.class)
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

We may even require that all actions extend some ActionBase class:

@RequestScoped
@Secure
@Transactional
@Production
@Stereotype(requiredTypes=ActionBase.class)
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}

2.7.2. Declaring the stereotypes for a Web Bean using annotations

Stereotype annotations may be applied to a Web Bean implementation class or producer method.

@Action
public class LoginAction { ... }

The default deployment type and default scope declared by the stereotype may be overridden by the Web Bean:

@Mock @ApplicationScoped @Action
public class MockLoginAction extends LoginAction { ... }

Multiple stereotypes may be applied to the same Web Bean:

@Dao @Action
public class LoginAction { ... }

2.7.3. Declaring the stereotypes for a Web Bean using XML

If the Web Bean is declared in web-beans.xml, stereotypes may be declared using the stereotype annotation type name:

<myapp:LoginAction>
    <myfwk:Action/>
</myapp:LoginAction>

If any stereotype is specified in XML, the stereotypes appearing on the implementation class or producer method are ignored and all stereotypes must be explicitly specified in XML.

Otherwise, if no stereotypes are specified in XML, the stereotype annotations that appear on the implementation class or producer method are used. If no stereotype annotations appear on the implementation class or producer method, the Web Bean has no stereotypes.

2.7.4. Stereotype restrictions

A stereotype may place certain restrictions upon the Web Beans that declare the stereotype.

If a stereotype declares a requiredType, and the Web Bean API types do not include the type, a DefinitionException is thrown by the Web Bean manager at initialization time.

If a stereotype explicitly declares a set of scope types using supportedScopes, and the Web Bean scope is not in that set, a DefinitionException is thrown by the Web Bean manager at initialization time.

If a Web Bean declares multiple stereotypes, it must satisfy every restriction declared by every declared stereotype.

2.7.5. Built-in stereotypes

Web Beans provides a built-in stereotype. The @Model stereotype is intended for use with Web Beans that define the model layer of an MVC web application architecture such as JSF:

@Named
@RequestScoped
@Stereotype
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Model {}

In addition, the special-purpose @Interceptor and @Decorator stereotypes are defined in Chapter 6, Interceptors and decorators.

2.8. Specialization

If two Web Beans both support a certain API type, and share at least one binding type, then they are both eligible for injection to any injection point with that declared type and binding type. The Web Bean manager will choose the Web Bean with the highest priority enabled deployment type.

Consider the following Web Beans:

@Current @Asynchronous 
public class AsynchronousService implements Service{ 
    ... 
}
@Mock @Current 
public class MockAsynchronousService extends AsynchronousService { 
    ... 
}

Suppose that the deployment type @Mock is enabled:

<WebBeans>
    <Deploy>
        <Standard/>
        <Production/>
        <myfwk:Mock/>
    </Deploy>
</WebBeans>

Then the following attribute will receive an instance of MockAsynchronousService:

@Current Service service;

However, if the Web Bean with the lower priority deployment type declares a binding annotation that is not declared by the Web Bean with the higher priority deployment type, then the Web Bean with the higher priority deployment type will not be eligible for injection to an injection point with that binding type.

Therefore, the following attribute will receive an instance of AsynchronousService even though the deployment type @Mock is enabled:

@Current @Asynchronous Service service;

This is a useful feature in many circumstances, however, it is not always what is intended by the developer.

The only way one Web Bean can completely override a lower-priority Web Bean at all injection points is if it implements all the API types and declares all the binding types of the lower-priority Web Bean. However, if the lower-priority Web Bean declares a producer method, then even this is not enough to ensure that the lower-priority Web Bean is never called!

To help prevent developer error, the first Web Bean may:

  • directly extend the implementation of the lower-priority Web Bean (or directly override it, in the case of a producer method Web Bean), and

  • explicitly declare that it specializes the lower-priority Web Bean.

Then the first Web Bean will inherit the binding types and name of the lower-priority Web Bean. For example, the following Web Bean would have the inherited binding types @Current and @Asynchronous:

@Mock @Specializes
public class MockAsynchronousService extends AsynchronousService { 
    ... 
}

The binding types of a Web Bean that specializes a lower-priority Web Bean include all binding types of the lower-priority Web Bean, together with binding types declared explicitly by the first Web Bean.

If a Web Bean specializes a lower-priority Web Bean with a name, the name of the first Web Bean is the same as the name of the lower-priority Web Bean. If the first Web Bean declares a name explicitly, a DefinitionException is thrown by the Web Bean manager at initialization time.

For example, if AsynchronousService declared a name:

@Current @Asynchronous @Named("asyncService")
public class AsynchronousService implements Service{ 
    ... 
}

Then the name will automatically be inherited by MockAsynchronousService.

When an enabled Web Bean specializes a lower-priority Web Bean, we can be certain that the lower-priority Web Bean is never instantiated or called by the Web Bean manager. Even if the lower-priority Web Bean defines a producer method, the method will be called upon an instance of the first Web Bean.

Specialization applies only to simple Web Beans, as defined in Section 3.2.6, “Specializing a simple Web Bean”, enterprise Web Beans, as defined in Section 3.3.6, “Specializing an enterprise Web Bean” and producer methods, as defined in Section 3.4.5, “Specializing a producer method”.

2.8.1. Direct and indirect specialization

The @Specializes annotation or <Specializes> XML element is used to indicate that one Web Bean directly specializes another Web Bean.

Formally, a Web Bean X is said to specialize another Web Bean Y if either:

  • X directly specializes Y, or

  • a Web Bean Z exists, such that X directly specializes Z and Z specializes Y.

If X specializes Y but does not directly specialize Y, we say that X indirectly specializes Y.

If, in a particular deployment, a Web Bean with a certain API type and set of binding types is not specialized by any other enabled Web Bean, we call it the most specialized Web Bean for that combination of type and binding types in that deployment.

Any producer methods, disposal methods (see Section 3.4.6, “Disposal methods”) or observer methods (see Section 7.5, “Observer methods”) declared by a Web Bean are invoked upon an instance of the most specialized enabled Web Bean that specializes the Web Bean, as defined by Section 5.6, “Lifecycle of producer methods” and Section 7.4, “Observer invocation”.

2.8.2. Inconsistent specialization

If, in a particular deployment, either

  • some enabled Web Bean X specializes another enabled Web Bean Y and X does not have a higher precedence than Y, or

  • more than one enabled Web Bean directly specializes the same Web Bean

we say that inconsistent specialization exists, and an InconsistentSpecializationException is thrown by the Web Bean manager at initialization time.