Chapter 2. Concepts

A Java EE component is a bean if the lifecycle of its instances may be managed by the container according to the lifecycle context model defined in Chapter 6, Scopes and contexts. A bean may bear metadata defining its lifecycle and interactions with other components.

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

A bean comprises the following attributes:

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

In most cases, a bean developer provides the bean implementation by writing business logic in Java code. The developer then defines the remaining attributes by explicitly annotating the bean class, or by allowing them to be defaulted by the container, as specified in Chapter 3, Programming model. In certain other cases—for example, Java EE component environment resources, defined in Section 3.5, “Resources”—the developer provides only the annotations and the bean implementation is provided by the container.

The bean types and qualifiers of a bean determine where its instances will be injected by the container, as defined in Chapter 5, Dependency injection, lookup and EL.

The bean developer may also create interceptors and/or decorators or reuse existing interceptors and/or decorators. The interceptor bindings of a bean determine which interceptors will be applied at runtime. The bean types and qualifiers of a bean determine which decorators will be applied at runtime. Interceptors are defined by Java interceptors specification, and interceptor bindings are specified in Chapter 9, Interceptor bindings. Decorators are defined in Chapter 8, Decorators.

2.1. Functionality provided by the container to the bean

A bean is provided by the container with the following capabilities:

2.2. Bean types

A bean type defines a client-visible type of the bean. A bean may have multiple bean types. For example, the following bean has four bean types:

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

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

Meanwhile, this session bean has only the local interfaces BookShop and Auditable, along with Object, as bean 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 (unrestricted) set of bean types for a bean are defined in Section 3.1.2, “Bean types of a managed bean”, Section 3.2.2, “Bean types of a session bean”, Section 3.3.1, “Bean types of a producer method”, Section 3.4.1, “Bean types of a producer field” and Section 3.5.2, “Bean types of a resource”.

All beans have the bean type java.lang.Object.

The bean types of a bean are used by the rules of typesafe resolution defined in Section 5.2, “Typesafe resolution”.

2.2.1. Legal bean types

Almost any Java type may be a bean type of a bean:

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

  • A bean type may be a parameterized type with actual type parameters and type variables.

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

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

  • A bean type may be a raw type.

A type variable is not a legal bean type. A parameterized type that contains a wildcard type parameter is not a legal bean type.

Note that certain additional restrictions are specified in Section 5.4.1, “Unproxyable bean types” for beans with a normal scope, as defined in Section 6.3, “Normal scopes and pseudo-scopes”.

2.2.2. Restricting the bean types of a bean

The bean types of a bean may be restricted by annotating the bean class or producer method or field with the annotation @javax.enterprise.inject.Typed.

@Typed(Shop.class)
public class BookShop
        extends Business
        implements Shop<Book> { 
    ... 
}

When a @Typed annotation is explicitly specified, only the types whose classes are explicitly listed using the value member, together with java.lang.Object, are bean types of the bean.

In the example, the bean has a two bean types: Shop<Book> and Object.

If a bean class or producer method or field specifies a @Typed annotation, and the value member specifies a class which does not correspond to a type in the unrestricted set of bean types of a bean, the container automatically detects the problem and treats it as a definition error.

2.2.3. Typecasting between bean types

A client of a bean may typecast its contextual reference to a bean to any bean type of the bean which is a Java interface. However, the client may not in general typecast its contextual reference to an arbitrary concrete bean type of the bean. For example, if our managed bean was injected to the following field:

@Inject Business biz;

Then the following typecast is legal:

Shop<Book> bookShop = (Shop<Book>) biz;

However, the following typecast is not legal and might result in an exception at runtime:

BookShop bookShop = (BookShop) biz;

2.3. Qualifiers

For a given bean type, there may be multiple 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 the PaymentProcessor interface. However, this approach creates a hard dependence between client and implementation—exactly what use of the interface was designed to avoid!

A qualifier type represents some client-visible semantic associated with a type that is satisfied by some implementations of the type (and not by others). For example, we could introduce qualifier types representing synchronicity and asynchronicity. In Java code, qualifier types are represented by annotations.

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

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

@Inject @Synchronous PaymentProcessor paymentProcessor;

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

@Inject @Asynchronous PaymentProcessor paymentProcessor;

The container inspects the qualifier annotations and type of the injected attribute to determine the bean instance to be injected, according to the rules of typesafe resolution defined in Section 5.2, “Typesafe resolution”.

An injection point may even specify multiple qualifiers.

Qualifier types are also used as event selectors by event consumers, as defined in Chapter 10, Events, and to bind decorators to beans, as specified in Chapter 8, Decorators.

2.3.1. Built-in qualifier types

Three standard qualifier types are defined in the package javax.enterprise.inject. In addition, the built-in qualifier type @Named is defined by the package javax.inject.

Every bean has the built-in qualifier @Any, even if it does not explicitly declare this qualifier, except for the special @New qualified beans defined in Section 3.12, “@New qualified beans”.

If a bean does not explicitly declare a qualifier other than @Named, the bean has exactly one additional qualifier, of type @Default. This is called the default qualifier.

The following declarations are equivalent:

@Default
public class Order { ... }
public class Order { ... }

Both declarations result in a bean with two qualifiers: @Any and @Default.

The following declaration results in a bean with three qualifiers: @Any, @Default and @Named("ord").

@Named("ord")
public class Order { ... }

The default qualifier is also assumed for any injection point that does not explicitly declare a qualifier, as defined in Section 3.10, “The default qualifier at injection points”. The following declarations, in which the use of the @Inject annotation identifies the constructor parameter as an injection point, are equivalent:

public class Order {
    @Inject
    public Order(@Default OrderProcessor processor) { ... }
}
public class Order {
    @Inject
    public Order(OrderProcessor processor) { ... }
}

2.3.2. Defining new qualifier types

A qualifier type is a Java annotation defined as @Target({METHOD, FIELD, PARAMETER, TYPE}) and @Retention(RUNTIME).

A qualifier type may be declared by specifying the @javax.inject.Qualifier meta-annotation.

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

A qualifier type may define annotation members.

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

2.3.3. Declaring the qualifiers of a bean

The qualifiers of a bean are declared by annotating the bean class or producer method or field with the qualifier types.

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

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

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

}

Any bean may declare multiple qualifier types.

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

2.3.4. Specifying qualifiers of an injected field

Qualifier types may be applied to injected fields (see Section 3.8, “Injected fields”) to determine the bean that is injected, according to the rules of typesafe resolution defined in Section 5.2, “Typesafe resolution”.

@Inject @LDAP Authenticator authenticator;

A bean may only be injected to an injection point if it has all the qualifiers of the injection point.

@Inject @Synchronous @Reliable PaymentProcessor paymentProcessor;
@Inject @All List<Product> catalog;
@Inject @WishList List<Product> wishList;

2.3.5. Specifying qualifiers of a method or constructor parameter

Qualifier types may be applied to parameters of producer methods, initializer methods, disposer methods, observer methods or bean constructors (see Chapter 3, Programming model) to determine the bean instance that is passed when the method is called by the container. The container uses the rules of typesafe resolution defined in Section 5.2, “Typesafe resolution” to determine values for these parameters.

For example, when the container 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;
}

2.4. Scopes

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 explicitly 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 lifecycle 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 beans have a scope. The scope of a bean determines the lifecycle of its instances, and which instances of the bean are visible to instances of other beans, as defined in Chapter 6, 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 five standard scope types defined by this specification, all defined in the package javax.enterprise.context.

If an interceptor or decorator has any scope other than @Dependent, non-portable behavior results.

2.4.2. Defining new scope types

A scope type is a Java annotation defined as @Target({TYPE, METHOD, FIELD}) and @Retention(RUNTIME). All scope types must also specify the @javax.inject.Scope or @javax.enterprise.context.NormalScope meta-annotation.

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

@Inherited
@NormalScope
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface BusinessProcessScoped {}

Custom scopes are normally defined by portable extensions, which must also provide a context object, as defined in Section 6.2, “The Context interface”, that implements the custom scope.

2.4.3. Declaring the bean scope

The scope of a bean is defined by annotating the bean class or producer method or field with a scope type.

A bean class or producer method or field may specify at most one scope type annotation. If a bean class or producer method or field specifies multiple scope type annotations, the container automatically detects the problem and treats it as a definition error.

public class Shop {

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

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

}

Likewise, a 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 bean”.

2.4.4. Default scope

When no scope is explicitly declared by annotating the bean class or producer method or field the scope of a bean is defaulted.

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

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

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

  • If there are two different stereotypes declared by the bean that declare different default scopes, then there is no default scope and the bean must explicitly declare a scope. If it does not explicitly declare a scope, the container automatically detects the problem and treats it as a definition error.

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

2.5. Bean EL names

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

The following strings are valid EL names:

org.mydomain.myapp.settings
orderManager

There is no relationship between the EL name of a session bean and the EJB name of the bean.

Subject to the restrictions defined in Section 5.3.1, “Ambiguous EL names”, multiple beans may share the same EL name.

Bean EL names allow the direct use of beans in JSP or JSF pages, as defined in Section 12.4, “Integration with Unified EL”. For example, a bean with the name products could be used like this:

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

Bean EL names are used by the rules of EL name resolution defined in Section 5.3, “EL name resolution”.

2.5.1. Declaring the bean EL name

To specify the EL name of a bean, the qualifier @javax.inject.Named is applied to the bean class or producer method or field. This bean is named currentOrder:

@Named("currentOrder")
public class Order { ... }

If the @Named annotation does not specify the value member, the EL name is defaulted.

2.5.2. Default bean EL names

In the following circumstances, a default EL name must be assigned by the container:

  • A bean class or producer method or field of a bean declares a @Named annotation and no EL name is explicitly specified by the value member.

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

The default name for a bean depends upon the bean implementation. The rules for determining the default name for a bean are defined in Section 3.1.5, “Default name for a managed bean”, Section 3.2.5, “Default name for a session bean”, Section 3.3.8, “Default name for a producer method” and Section 3.4.3, “Default name for a producer field”.

2.5.3. Beans with no EL name

If @Named is not declared by the bean, nor by its stereotypes, a bean has no EL name.

If an interceptor or decorator has a name, non-portable behavior results.

2.6. Alternatives

An alternative is a bean that must be explicitly declared in the beans.xml file if it should be available for lookup, injection or EL resolution.

2.6.1. Declaring an alternative

An alternative may be declared by annotating the bean class or producer method or field with the @Alternative annotation.

@Alternative
public class MockOrder extends Order { ... }

Alternatively, an alternative may be declared by annotating a bean, producer method or producer field with a stereotype that declares an @Alternative annotation.

If an interceptor or decorator is an alternative, non-portable behavior results.

2.7. Stereotypes

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

A stereotype encapsulates any combination of:

  • a default scope, and

  • a set of interceptor bindings.

A stereotype may also specify that:

  • all beans with the stereotype have defaulted bean EL names, or that

  • all beans with the stereotype are alternatives.

A bean may declare zero, one or multiple stereotypes.

2.7.1. Defining new stereotypes

A bean stereotype is a Java annotation defined as @Target({TYPE, METHOD, FIELD}), @Target(TYPE), @Target(METHOD), @Target(FIELD) or @Target({METHOD, FIELD}) and @Retention(RUNTIME).

A stereotype may be declared by specifying the @javax.enterprise.inject.Stereotype meta-annotation.

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

2.7.1.1. Declaring the default scope for a stereotype

The default scope of a stereotype is defined by annotating the stereotype with a scope type. A stereotype may declare at most one scope. If a stereotype declares more than one scope, the container automatically detects the problem and treats it as a definition error.

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

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

Then actions would have scope @RequestScoped unless the scope is explicitly specified by the bean.

2.7.1.2. Specifying interceptor bindings for a stereotype

The interceptor bindings of a stereotype are defined by annotating the stereotype with the interceptor binding types. A stereotype may declare zero, one or multiple interceptor bindings, as defined in Section 9.1.2, “Interceptor bindings for stereotypes”.

We may specify interceptor bindings that apply to all actions:

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

2.7.1.3. Declaring a @Named stereotype

A stereotype may declare an empty @Named annotation, which specifies that every bean with the stereotype has a defaulted name when a name is not explicitly specified by the bean.

If a stereotype declares a non-empty @Named annotation, the container automatically detects the problem and treats it as a definition error.

We may specify that all actions have names:

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

A stereotype should not declare any qualifier annotation other than @Named. If a stereotype declares any other qualifier annotation, non-portable behavior results.

A stereotype should not be annotated @Typed. If a stereotype is annotated @Typed, non-portable behavior results.

2.7.1.4. Declaring an @Alternative stereotype

A stereotype may declare an @Alternative annotation, which specifies that every bean with the stereotype is an alternative.

We may specify that all mock objects are alternatives:

@Alternative
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Mock {}

2.7.1.5. Stereotypes with additional stereotypes

A stereotype may declare other stereotypes.

@Auditable
@Action
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface AuditableAction {}

Stereotype declarations are transitive—a stereotype declared by a second stereotype is inherited by all beans and other stereotypes that declare the second stereotype.

Stereotypes declared @Target(TYPE) may not be applied to stereotypes declared @Target({TYPE, METHOD, FIELD}), @Target(METHOD), @Target(FIELD) or @Target({METHOD, FIELD}).

2.7.2. Declaring the stereotypes for a bean

Stereotype annotations may be applied to a bean class or producer method or field.

@Action
public class LoginAction { ... }

The default scope declared by the stereotype may be overridden by the bean:

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

Multiple stereotypes may be applied to the same bean:

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

2.7.3. Built-in stereotypes

The built-in stereotype @javax.enterprise.inject.Model is intended for use with beans that define the model layer of an MVC web application architecture such as JSF:

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

In addition, the special-purpose @Interceptor and @Decorator stereotypes are defined in Section 9.2, “Declaring the interceptor bindings of an interceptor” and Section 8.1.1, “Declaring a decorator”.

2.8. Problems detected automatically by the container

When the application violates a rule defined by this specification, the container automatically detects the problem. There are three kinds of problem:

  • Definition errors—occur when a single bean definition violates the rules of this specification

  • Deployment problems—occur when there are problems resolving dependencies, or inconsistent specialization, in a particular deployment

  • Exceptions—occur at runtime

Definition errors are developer errors. They may be detected by tooling at development time, and are also detected by the container at initialization time. If a definition error exists in a deployment, initialization will be aborted by the container.

Deployment problems are detected by the container at initialization time. If a deployment problem exists in a deployment, initialization will be aborted by the container.

The container is permitted to define a non-portable mode, for use at development time, in which some definition errors and deployment problems do not cause application initialization to abort.

Exceptions represent problems that may not be detected until they actually occur at runtime. All exceptions defined by this specification are unchecked exceptions. All exceptions defined by this specification may be safely caught and handled by the application.