[[concepts]]

== Concepts

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.
A bean may bear metadata defining its lifecycle and interactions with other beans.

A bean comprises the following attributes:

* A (nonempty) set of bean types
* A (nonempty) set of qualifiers
* A scope
* Optionally, a bean name
* A set of interceptor bindings
* A bean implementation


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

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

The bean types and qualifiers of a bean determine where its instances will be injected by the container, as defined in <<injection_and_resolution>>.

The bean developer may also create interceptors or reuse existing interceptors.
The interceptor bindings of a bean determine which interceptors will be applied at runtime.
Interceptors are defined by Jakarta EE interceptors specification, and interceptor bindings are specified in <<interceptors>>.

In {cdi_full} environment, the bean developer may also create decorators or reuse existing decorators.
The bean types and qualifiers of a bean determine which decorators will be applied at runtime.
Decorators are defined in <<decorators>>.

[[capabilities]]

=== Functionality provided by the container to the bean

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

* transparent creation and destruction and scoping to a particular context, specified in <<contexts>> and <<lifecycle>>,
* scoped resolution by bean type and qualifier annotation type when injected into a Java-based client, as defined by <<typesafe_resolution>>,
* lifecycle callbacks and automatic injection of other bean instances, specified in <<implementation>> and <<injection_and_resolution>>,
* method interception, callback interception, as defined in <<interceptors>>, and
* event notification, as defined in <<events>>.

In {cdi_full} environment, the container also provides the following capabilities:

* decoration, as defined in <<decorators>>.


[[bean_types]]

=== 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:

[source, java]
----
public class BookShop
        extends Business
        implements Shop<Book> { 
    ... 
}
----

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

The rules for determining the (unrestricted) set of bean types for a bean are defined in <<managed_bean_types>>, <<producer_method_types>> and <<producer_field_types>>.

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

[[legal_bean_types]]

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

However, some Java types are not legal bean types :

* A type variable is not a legal bean type.
* A parameterized type that contains a wildcard type parameter is not a legal bean type.
* An array type whose component type is not a legal bean type.

Note that certain additional restrictions are specified in <<unproxyable>> for beans with a normal scope, as defined in <<normal_scope>>.

[[restricting_bean_types]]

==== 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 `@jakarta.enterprise.inject.Typed`.

[source, java]
----
@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.

[[typecasting_between_bean_types]]

==== 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:

[source, java]
----
@Inject Business biz;
----

Then the following typecast is legal:

[source, java]
----
Shop<Book> bookShop = (Shop<Book>) biz;
----

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

[source, java]
----
BookShop bookShop = (BookShop) biz;
----

[[qualifiers]]

=== 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`:

[source, java]
----
class SynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}
----

[source, java]
----
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.

[source, java]
----
@Synchronous
class SynchronousPaymentProcessor 
        implements PaymentProcessor { 
    ... 
}
----

[source, java]
----
@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:

[source, java]
----
@Inject @Synchronous PaymentProcessor paymentProcessor;
----

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

[source, java]
----
@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 <<typesafe_resolution>>.

An injection point may even specify multiple qualifiers.

Qualifier types are also used as event selectors by event consumers, as defined in <<events>>.

In {cdi_full} environment, qualifier types are also used to bind decorators to beans, as specified in <<decorators>>.

[[builtin_qualifiers]]

==== Built-in qualifier types

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

Every bean has the built-in qualifier `@Any`, even if it does not explicitly declare this qualifier.

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

The following declarations are equivalent:

[source, java]
----
@Default
public class Order { ... }
----

[source, java]
----
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")`.

[source, java]
----
@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 <<injection_point_default_qualifier>>.
The following declarations, in which the use of the `@Inject` annotation identifies the constructor parameter as an injection point, are equivalent:

[source, java]
----
public class Order {
    @Inject
    public Order(@Default OrderProcessor processor) { ... }
}
----

[source, java]
----
public class Order {
    @Inject
    public Order(OrderProcessor processor) { ... }
}
----

[[defining_qualifier_types]]

==== Defining new qualifier types

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

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

[source, java]
----
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Synchronous {}
----

[source, java]
----
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Asynchronous {}
----

A qualifier type may define annotation members.

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

[[declaring_bean_qualifiers]]

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

[source, java]
----
@LDAP 
class LdapAuthenticator 
        implements Authenticator {
    ...
}
----

[source, java]
----
public class Shop {

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

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

}
----

Any bean may declare multiple qualifier types.

[source, java]
----
@Synchronous @Reliable
class SynchronousReliablePaymentProcessor 
        implements PaymentProcessor {
    ...
}
----

[[injected_field_qualifiers]]

==== Specifying qualifiers of an injected field

Qualifier types may be applied to injected fields (see <<injected_fields>>) to determine the bean that is injected, according to the rules of typesafe resolution defined in <<typesafe_resolution>>.

[source, java]
----
@Inject @LDAP Authenticator authenticator;
----

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

[source, java]
----
@Inject @Synchronous @Reliable PaymentProcessor paymentProcessor;
----

[source, java]
----
@Inject @All List<Product> catalog;
----

[source, java]
----
@Inject @WishList List<Product> wishList;
----

[[method_constructor_parameter_qualifiers]]

==== 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 <<implementation>>) 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 <<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:

[source, java]
----
@Produces
PaymentProcessor getPaymentProcessor(@Synchronous PaymentProcessor sync,
                                     @Asynchronous PaymentProcessor async) {
    return isSynchronous() ? sync : async;
}
----

[[repeating_qualifiers]]

==== Repeating qualifiers

In some cases, it may be useful to have a repeated qualifier for your type safe resolution.  A repeated qualifier behaves just as any other qualifier does.  For example, the below qualifier is a repeatable qualifier

[source, java]
----
@Target({ PARAMETER, FIELD, METHOD, TYPE })
@Retention(RUNTIME)
@Documented
@Qualifier
@Repeatable(Locations.class)
public @interface Location {
    String value();
}

@Target({ PARAMETER, FIELD, METHOD, TYPE })
@Retention(RUNTIME)
public @interface Locations {
    Location[] value();
}
----

Now you can define appropriate producers and injection points for repeated qualifiers.

[source, java]
----
@Produces
@Location("north")
@Location("south")
public Coordinate createCoordinate() {
   // ...
}

@Inject
@Location("north")
@Location("south")
private Coordinate coordinate;
----

A partial match injection point will still work in this case (from the same producer method)

[source, java]
----
@Inject
@Location("south")
private Coordinate coordinate;
----

However, adding the follow producer method will continue to give you an ambiguous resolution error (assuming the other producer exists as well)

[source, java]
----
@Produces
@Location("south")
public Coordinate createSouthCoordinate() {
   // ...
}
----

[[scopes]]

=== Scopes

Scoped objects, 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 <<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:

[source, java]
----
@Produces @SessionScoped User getCurrentUser() { ... }
----

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

[source, java]
----
@ConversationScoped
public class Order { ... }
----

[NOTE]
====
Session scope and conversation scope are only available in {cdi_full}.
====

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

[source, java]
----
@Produces @RequestScoped @Named("orders") 
List<Order> getOrderSearchResults() { ... }
----

The set of scope types is extensible.

[[builtin_scopes]]

==== Built-in scope types

There are three standard scope types defined in {cdi_lite}, all defined in the package `jakarta.enterprise.context`.

* The container must provide an implementation of the `@RequestScoped` and `@ApplicationScoped` annotations defined in <<builtin_contexts>>.
Note that these standard scopes can be extended by third-party extensions as defined in <<context>>
* Finally, there is a `@Dependent` pseudo-scope for dependent objects, as defined in <<dependent_context>>.


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

[[defining_new_scope_type]]

==== Defining new scope types

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

A scope type must not have any attributes.
If a scope type has attributes, non-portable behavior results.

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

[source, java]
----
@Inherited
@NormalScope
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface BusinessProcessScoped {}
----

Custom scopes are normally defined by extensions, which must also provide an implementation of the `Context` interface, as defined in <<context>>, that implements the custom scope.
Portable extensions provide a _context object_ directly, while build compatible extensions provide a class that the container has to instantiate to obtain the context object.

[[declaring_bean_scope]]

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

[source, java]
----
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:

[source, java]
----
@BusinessProcessScoped
public class Order { ... }
----

Alternatively, a scope type may be specified using a stereotype annotation, as defined in <<declaring_stereotypes>>.

[[default_scope]]

==== 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 present on the bean, directly, indirectly, or transitively, 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.

[[default_bean_discovery]]

=== Default bean discovery mode

The default _bean discovery mode_ for a bean archive is `annotated`, and such a bean archive is said to be an _implicit bean archive_ as defined in <<bean_archive>>.

If the _bean discovery mode_ is `annotated` then:

* bean classes that don't have _bean defining annotation_ (as defined in <<bean_defining_annotations>>) are not discovered, and
* producer methods (as defined in <<producer_method>>) whose bean class does not have a _bean defining annotation_ are not discovered, and
* producer fields (as defined in <<producer_field>>) whose bean class does not have a _bean defining annotation_ are not discovered, and
* disposer methods (as defined in <<disposer_method>>) whose bean class does not have a _bean defining annotation_ are not discovered, and
* observer methods (as defined in <<observes>>) whose bean class does not have a _bean defining annotation_ are not discovered.

[[bean_defining_annotations]]

==== Bean defining annotations

A bean class may have a _bean defining annotation_, allowing it to be placed anywhere in an application, as defined in <<bean_archive>>.
A bean class with a _bean defining annotation_ is said to be an _implicit bean_.

The set of bean defining annotations contains:

* `@ApplicationScoped` and `@RequestScoped` annotations,
* all other normal scope types,
* `@Interceptor` annotation,
* all stereotype annotations (i.e. annotations annotated with `@Stereotype`),
* and the `@Dependent` scope annotation.

If one of these annotations is declared on a bean class, then the bean class is said to have a bean defining annotation.
For example, this dependent scoped bean has a bean defining annotation:

[source,java]
----
@Dependent
public class BookShop
        extends Business
        implements Shop<Book> {
    ...
}
----

whilst this dependent scoped bean does not have a bean defining annotation:

[source,java]
----
public class CoffeeShop
        extends Business
        implements Shop<Coffee> {
    ...
}
----

Note that to ensure compatibility with other Jakarta Dependency Injection implementations, all pseudo-scope annotations except `@Dependent` *are not* bean defining annotations.
However, a stereotype annotation including a pseudo-scope annotation *is* a bean defining annotation.

[[names]]

=== Bean names

A bean may have a _bean name_.
A bean with a name may be referred to by its name when used in a non typesafe environment (like the Unified Expression Language). A valid bean name is a period-separated list of valid EL identifiers.

The following strings are valid bean names:

----
com.acme.settings
----

----
orderManager
----

Subject to the restrictions defined in <<ambig_names>>, multiple beans may share the same bean name.

Bean names are used by the rules of bean name resolution defined in <<name_resolution>>.

[[declaring_bean_name]]

==== Declaring the bean name

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

[source, java]
----
@Named("currentOrder")
public class Order { ... }
----

[[default_name]]

==== Default bean names

In the following circumstances, a _default name_ must be assigned by the container:

* A bean class or producer method or field of a bean declares a `@Named` annotation and no bean 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 a bean name.


The default name for a bean depends upon the kind of the bean.
The rules for determining the default name for a bean are defined in <<managed_bean_name>>, <<producer_method_name>> and <<producer_field_name>>.

[[beans_with_no_name]]

==== Beans with no name

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

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

[[alternatives]]

=== Alternatives

An _alternative_ is a bean that must be explicitly selected if it should be available for lookup, injection or name resolution.

[[declaring_alternative]]

==== Declaring an alternative

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

[source, java]
----
@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 is an alternative, non-portable behavior results.

[[stereotypes]]

=== 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 names, or that
* all beans with the stereotype are alternatives, or that
* all beans with the stereotype have predefined `@Priority`.


A bean may declare zero, one or multiple stereotypes.

[[defining_new_stereotype]]

==== Defining new stereotypes

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

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

[source, java]
----
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}
----

[[stereotype_default_scope]]

===== 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:

[source, java]
----
@RequestScoped
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}
----

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

[[specify_stereotype_interceptor_bindings]]

===== 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 <<stereotype_interceptor_bindings>>.

We may specify interceptor bindings that apply to all actions:

[source, java]
----
@RequestScoped
@Secure
@Transactional
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Action {}
----

[[named_stereotype]]

===== 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.
A `@Named` qualifier declared by a stereotype is not added to the qualifiers of a bean with the stereotype.

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 bean names:

[source, java]
----
@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.

[[alternative_stereotype]]

===== 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:

[source, java]
----
@Alternative
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Mock {}
----

[[priority_stereotype]]

===== Declaring stereotype with `@Priority`

A stereotype may declare a `@Priority` annotation which functions as a means of enabling and ordering affected beans.

If there are two different stereotypes present on a bean, directly, indirectly, or transitively, that declare different priority values, then the bean must explicitly declare a `@Priority` annotation.
If the bean does not explicitly declare priority, the container automatically detects the problem and treats it as a definition error.

If a bean explicitly declares priority, any priority values declared by stereotypes are ignored.

Following sample shows a stereotype that can be used to mark bean as globally enabled alternative:

[source, java]
----
@Alternative
@Priority(Interceptor.Priority.APPLICATION + 5)
@Stereotype
@Target(TYPE)
@Retention(RUNTIME)
public @interface Mock {}
----

[[stereotypes_with_additional_stereotypes]]

===== Stereotypes with additional stereotypes

A stereotype may declare other stereotypes.

[source, java]
----
@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})`.

[[declaring_stereotypes]]

==== Declaring the stereotypes for a bean

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

[source, java]
----
@Action
public class LoginAction { ... }
----

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

[source, java]
----
@Mock @ApplicationScoped @Action
public class MockLoginAction extends LoginAction { ... }
----

Multiple stereotypes may be applied to the same bean:

[source, java]
----
@Dao @Action
public class LoginAction { ... }
----

[[builtin_stereotypes]]

==== Built-in stereotypes

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

[source, java]
----
@Named
@RequestScoped
@Stereotype
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface Model {}
----

In addition, the special-purpose `@Interceptor` stereotype is defined in <<declaring_interceptor>>.

[[exceptions]]

=== 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.
If a definition error exists, the container must throw a subclass of `jakarta.enterprise.inject.spi.DefinitionException`.
* Deployment problems - occur when there are problems resolving dependencies, or inconsistent specialization (in {cdi_full}), in a particular deployment.
If a deployment problem occurs, the container must throw a subclass of `jakarta.enterprise.inject.spi.DeploymentException`.
* 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.

