[[decorators]]

== Decorators

A _decorator_ implements one or more bean types and intercepts business method invocations of beans which implement those bean types.
These bean types are called _decorated types_.

Decorators are superficially similar to interceptors, but because they directly implement operations with business semantics, they are able to implement business logic and, conversely, unable to implement the cross-cutting concerns for which interceptors are optimized.

Decorators may be associated with any managed bean that is not itself an interceptor or decorator, or with any built-in bean other than the built-in bean with type `BeanManager` and qualifier `@Default`.
Decorators are not automatically applied to the return value of a producer method or the current value of a producer field.

A decorator instance is a dependent object of the object it decorates.

[[decorator_bean]]

=== Decorator beans

A decorator is a managed bean.
The set of decorated types of a decorator includes all bean types of the managed bean which are Java interfaces, except for `java.io.Serializable`. The decorator bean class and its superclasses are not decorated types of the decorator.
The decorator class may be abstract.

If the set of decorated types of a decorator is empty, the container automatically detects the problem and treats it as a definition error.

If a decorator declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error.

[[decorator_annotation]]

==== Declaring a decorator

A decorator is declared by annotating the bean class with the `@jakarta.decorator.Decorator` stereotype.

[source, java]
----
@Decorator @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION)
class TimestampLogger implements Logger { ... }
----

[[delegate_attribute]]

==== Decorator delegate injection points

All decorators have a _delegate injection point_.
A delegate injection point is an injection point of the bean class.
The type and qualifiers of the injection point are called the _delegate type_ and _delegate qualifiers_.
The decorator applies to beans that are assignable to the delegate injection point.

The delegate injection point must be declared by annotating the injection point with the annotation `@jakarta.decorator.Delegate`:

[source, java]
----
@Decorator @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION)
class TimestampLogger implements Logger {
    @Inject @Delegate @Any Logger logger;
    ...
}
----

[source, java]
----
@Decorator @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION)
class TimestampLogger implements Logger {
    private Logger logger;
    
    @Inject
    public TimestampLogger(@Delegate @Debug Logger logger) {
        this.logger=logger;
    }
    ...
}
----

A decorator must have exactly one delegate injection point.
If a decorator has more than one delegate injection point, or does not have a delegate injection point, the container automatically detects the problem and treats it as a definition error.

The delegate injection point must be an injected field, initializer method parameter or bean constructor method parameter.
If an injection point that is not an injected field, initializer method parameter or bean constructor method parameter is annotated `@Delegate`, the container automatically detects the problem and treats it as a definition error.

If a bean class that is not a decorator has an injection point annotated `@Delegate`, the container automatically detects the problem and treats it as a definition error.

The container must inject a _delegate_ object to the delegate injection point.
The delegate object implements the delegate type and delegates method invocations to remaining uninvoked decorators and eventually to the bean.
When the container calls a decorator during business method interception, the decorator may invoke any method of the delegate object.

[source, java]
----
@Decorator @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION)
class TimestampLogger implements Logger { 
    @Inject @Delegate @Any Logger logger; 
 
    void log(String message) {
        logger.log( timestamp() + ": " + message );
    }
    ...
}
----

If a decorator invokes the delegate object at any other time, the invoked method throws an `IllegalStateException`.

[[decorated_types]]

==== Decorated types of a decorator

The delegate type of a decorator must implement or extend every decorated type (with exactly the same type parameters). If the delegate type does not implement or extend a decorated type of the decorator (or specifies different type parameters), the container automatically detects the problem and treats it as a definition error.

A decorator is not required to implement the delegate type.

A decorator may be an abstract Java class, and is not required to implement every method of every decorated type.
Whenever the decorator does not implement a method of the decorated type, the container will provide an implicit implementation that calls the method on the delegate.
If a decorator has abstract methods that are not declared by a decorated type, the container automatically detects the problem and treats it as a definition error.

The decorator intercepts every method which is declared by a decorated type of the decorator and is implemented by the bean class of the decorator.

[[enabled_decorators]]

=== Decorator enablement and ordering

This specification defines two methods of enabling and ordering decorators.
From Contexts and Dependency Injection 1.1 onwards the `@Priority` annotation allows a decorator to be enabled and ordered for an entire application.
Contexts and Dependency Injection 1.0 allowed only for a decorator to be enabled and ordered for a bean archive.

Decorators are called after interceptors.
Decorators enabled using `@Priority` are called before decorators enabled using `beans.xml`.

A decorator is said to be *enabled* if it is enabled in at least one bean archive or is listed in the final list of decorators for the application, as defined in <<after_type_discovery>>.

If a decorator is enabled for the application and for the bean archive, then the enablement from the bean archive is ignored by the container.  The decorator will only be executed once based on the `@Priority` annotation's invocation chain.

[[enabled_decorators_priority]]

==== Decorator enablement and ordering for an application


A decorator may be enabled for the entire application by applying the `@Priority` annotation, along with a priority value, on the decorator class.
Decorators with the smaller priority values are called first.
The order of more than one decorator with the same priority is undefined.

[source,java]
----
@Decorator @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION)
class TimestampLogger implements Logger {

   ...
}
----

The priority value ranges defined in the Java Interceptors specification section 5.5 should be used when defining decorator priorities.

[[enabled_decorators_bean_archive]]

==== Decorator enablement and ordering for a bean archive

A decorator may be  explicitly enabled by listing its bean class under the `<decorators>` element of the `beans.xml` file of the bean archive.

[source,xml]
----
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
        version="3.0">
   <decorators>
      <class>com.acme.myfwk.TimestampLogger</class>
      <class>com.acme.myfwk.IdentityLogger</class>
   </decorators>
</beans>
----

The order of the decorator declarations determines the decorator ordering.
Decorators which occur earlier in the list are called first.

Each child `<class>` element must specify the name of a decorator bean class.
If there is no class with the specified name, or if the class with the specified name is not a decorator bean class, the container automatically detects the problem and treats it as a deployment problem.

If the same class is listed twice under the `<decorators>` element, the container automatically detects the problem and treats it as a deployment problem.


[[decorator_resolution]]

=== Decorator resolution

The process of matching decorators to a certain bean is called _decorator resolution_.
A decorator is bound to a bean if:

* The bean is assignable to the delegate injection point according to the rules defined in <<typesafe_resolution>> (using <<delegate_assignable_parameters>>).
* The decorator is enabled in the bean archive containing the bean.


If a decorator matches a managed bean, the managed bean class must be a proxyable bean type, as defined in <<unproxyable>>.

For a custom implementation of the `Decorator` interface defined in <<decorator>>, the container calls `getDelegateType()`, `getDelegateQualifiers()` and `getDecoratedTypes()` to determine the delegate type and qualifiers and decorated types of the decorator.

A custom implementation of the `Decorator` interface may implement the <<prioritized, `Prioritized` interface>> to be enabled for the entire application with a priority value.

[[delegate_assignable_parameters]]

==== Assignability of raw and parameterized types for delegate injection points

Decorator delegate injection points have a special set of rules for determining assignability of raw and parameterized types, as an exception to <<assignable_parameters>>.

A raw bean type is considered assignable to a parameterized delegate type if the raw types are identical and all type parameters of the delegate type are either unbounded type variables or `java.lang.Object`.

A parameterized bean type is considered assignable to a parameterized delegate type if they have identical raw type and for each parameter:

* the delegate type parameter and the bean type parameter are actual types with identical raw type, and, if the type is parameterized, the bean type parameter is assignable to the delegate type parameter according to these rules, or
* the delegate type parameter is a wildcard, the bean type parameter is an actual type and the actual type is assignable to the upper bound, if any, of the wildcard and assignable from the lower bound, if any, of the wildcard, or
* the delegate type parameter is a wildcard, the bean type parameter is a type variable and the upper bound of the type variable is assignable to the upper bound, if any, of the wildcard and assignable from the lower bound, if any, of the wildcard, or
* the delegate type parameter and the bean type parameter are both type variables and the upper bound of the bean type parameter is assignable to the upper bound, if any, of the delegate type parameter, or
* the delegate type parameter is a type variable, the bean type parameter is an actual type, and the actual type is assignable to the upper bound, if any, of the type variable.


[[decorator_invocation]]

=== Decorator invocation

Whenever a business method is invoked on an instance of a bean with decorators, the container intercepts the business method invocation and, after processing all interceptors of the method, invokes decorators of the bean.

The container searches for the first decorator of the instance that implements the method that is being invoked as a business method.
If no such decorator exists, the container invokes the business method of the intercepted instance.
Otherwise, the container calls the method of the decorator.

When any decorator is invoked by the container, it may in turn invoke a method of the delegate.
The container intercepts the delegate invocation and searches for the first decorator of the instance such that:

* the decorator occurs after the decorator invoking the delegate, and
* the decorator implements the method that is being invoked upon the delegate.


If no such decorator exists, the container invokes the business method of the intercepted instance.
Otherwise, the container calls the method of the decorator.

[[decorator_additional_rules]]

=== Additional decorator rules

This chapter congregates various rules and limitations that apply to decorators in regard to other chapters of the specification.

==== Bean names

In addition to rules defined in <<beans_with_no_name>>, the following rules apply.

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

==== Alternatives

In addition to rules defined in <<declaring_alternative>>, the following rules apply.

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

=== Managed beans

In addition to rules defined in <<managed_beans>>, the following rules apply.

If the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error.

=== Producer methods

In addition to rules defined in <<declaring_producer_method>>, the following rules apply.

Decorators may not declare producer methods.
If a decorator has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error.

=== Producer fields

In addition to rules defined in <<declaring_producer_field>>, the following rules apply.

Decorators may not declare producer fields.
If a decorator has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error.

=== Disposer methods

In addition to rules defined in <<declaring_disposer_method>>, the following rules apply.

Decorators may not declare disposer methods.
If a decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error.

=== Unproxyable bean types

In addition to rules defined in <<unproxyable>>, the following rules apply.

A bean type must be proxyable if an injection point resolves to a bean:

* that has an associated decorator.

Otherwise, the container automatically detects the problem, and treats it as a deployment problem.
