type=page
status=published
title=Using Interceptors
next=interceptors003.html
prev=interceptors001.html
~~~~~~
= Using Interceptors


[[GKEDM]]

[[using-interceptors]]
Using Interceptors
------------------

To define an interceptor, use one of the interceptor metadata
annotations listed in link:interceptors001.html#GKECC[Table 57-1] within
the target class, or in a separate interceptor class. The following code
declares an `@AroundTimeout` interceptor method within a target class:

[source,oac_no_warn]
----
@Stateless
public class TimerBean {
    ...
    @Schedule(minute="*/1", hour="*")
    public void automaticTimerMethod() { ... }

    @AroundTimeout
    public void timeoutInterceptorMethod(InvocationContext ctx) { ... }
    ...
}
----

If you are using interceptor classes, use the
`javax.interceptor.Interceptors` annotation to declare one or more
interceptors at the class or method level of the target class. The
following code declares interceptors at the class level:

[source,oac_no_warn]
----
@Stateless
@Interceptors({PrimaryInterceptor.class, SecondaryInterceptor.class})
public class OrderBean { ... }
----

The following code declares a method-level interceptor class:

[source,oac_no_warn]
----
@Stateless
public class OrderBean {
    ...
    @Interceptors(OrderInterceptor.class)
    public void placeOrder(Order order) { ... }
    ...
}
----

[[GKECY]]

[[intercepting-method-invocations]]
Intercepting Method Invocations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Use the `@AroundInvoke` annotation to designate interceptor methods for
managed object methods. Only one around-invoke interceptor method per
class is allowed. Around-invoke interceptor methods have the following
form:

[source,oac_no_warn]
----
@AroundInvoke
visibility Object method-name(InvocationContext) throws Exception { ... }
----

For example:

[source,oac_no_warn]
----
@AroundInvoke
public void interceptOrder(InvocationContext ctx) { ... }
----

Around-invoke interceptor methods can have public, private, protected,
or package-level access, and must not be declared static or final.

An around-invoke interceptor can call any component or resource that is
callable by the target method on which it interposes, can have the same
security and transaction context as the target method, and can run in
the same Java virtual machine call stack as the target method.

Around-invoke interceptors can throw runtime exceptions and any
exception allowed by the `throws` clause of the target method. They may
catch and suppress exceptions, and then recover by calling the
`InvocationContext.proceed` method.

[[GKHMH]]

[[using-multiple-method-interceptors]]
Using Multiple Method Interceptors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use the `@Interceptors` annotation to declare multiple interceptors for
a target method or class:

[source,oac_no_warn]
----
@Interceptors({PrimaryInterceptor.class, SecondaryInterceptor.class,
        LastInterceptor.class})
public void updateInfo(String info) { ... }
----

The order of the interceptors in the `@Interceptors` annotation is the
order in which the interceptors are invoked.

You can also define multiple interceptors in the deployment descriptor.
The order of the interceptors in the deployment descriptor is the order
in which the interceptors will be invoked:

[source,oac_no_warn]
----
...
<interceptor-binding>
    <target-name>myapp.OrderBean</target-name>
    <interceptor-class>myapp.PrimaryInterceptor.class</interceptor-class>
    <interceptor-class>myapp.SecondaryInterceptor.class</interceptor-class>
    <interceptor-class>myapp.LastInterceptor.class</interceptor-class>
    <method-name>updateInfo</method-name>
</interceptor-binding>
...
----

To explicitly pass control to the next interceptor in the chain, call
the `InvocationContext.proceed` method.

Data can be shared across interceptors.

* The same `InvocationContext` instance is passed as an input parameter
to each interceptor method in the interceptor chain for a particular
target method. The `InvocationContext` instance's `contextData` property
is used to pass data across interceptor methods. The `contextData`
property is a `java.util.Map<String, Object>` object. Data stored in
`contextData` is accessible to interceptor methods further down the
interceptor chain.
* The data stored in `contextData` is not sharable across separate
target class method invocations. That is, a different
`InvocationContext` object is created for each invocation of the method
in the target class.

[[GKHOV]]

[[accessing-target-method-parameters-from-an-interceptor-class]]
Accessing Target Method Parameters from an Interceptor Class
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can use the `InvocationContext` instance passed to each
around-invoke method to access and modify the parameters of the target
method. The `parameters` property of `InvocationContext` is an array of
`Object` instances that corresponds to the parameter order of the target
method. For example, for the following target method, the `parameters`
property, in the `InvocationContext` instance passed to the
around-invoke interceptor method in `PrimaryInterceptor`, is an `Object`
array containing two `String` objects (`firstName` and `lastName`) and a
`Date` object (`date`):

[source,oac_no_warn]
----
@Interceptors(PrimaryInterceptor.class)
public void updateInfo(String firstName, String lastName, Date date) { ... }
----

You can access and modify the parameters by using the
`InvocationContext.getParameters` and `InvocationContext.setParameters`
methods, respectively.

[[GKECR]]

[[intercepting-lifecycle-callback-events]]
Intercepting Lifecycle Callback Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Interceptors for lifecycle callback events (around-construct,
post-construct, and pre-destroy) may be defined in the target class or
in interceptor classes. The `javax.interceptor.AroundConstruct`
annotation designates the method as an interceptor method that
interposes on the invocation of the target class's constructor. The
`javax.annotation.PostConstruct` annotation is used to designate a
method as a post-construct lifecycle event interceptor. The
`javax.annotation.PreDestroy` annotation is used to designate a method
as a pre-destroy lifecycle event interceptor.

Lifecycle event interceptors defined within the target class have the
following form:

[source,oac_no_warn]
----
void method-name() { ... }
----

For example:

[source,oac_no_warn]
----
@PostConstruct
void initialize() { ... }
----

Lifecycle event interceptors defined in an interceptor class have the
following form:

[source,oac_no_warn]
----
void method-name(InvocationContext) { ... }
----

For example:

[source,oac_no_warn]
----
@PreDestroy
void cleanup(InvocationContext ctx) { ... }
----

Lifecycle interceptor methods can have public, private, protected, or
package-level access, and must not be declared static or final.
Lifecycle interceptors may throw runtime exceptions but cannot throw
checked exceptions.

Lifecycle interceptor methods are called in an unspecified security and
transaction context. That is, portable Java EE applications should not
assume the lifecycle event interceptor method has access to a security
or transaction context. Only one interceptor method for each lifecycle
event (post-create and pre-destroy) is allowed per class.

[[sthref254]]

[[using-aroundconstruct-interceptor-methods]]
Using AroundConstruct Interceptor Methods
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

`@AroundConstruct` methods are interposed on the invocation of the
target class's constructor. Methods decorated with `@AroundConstruct`
may only be defined within interceptor classes or superclasses of
interceptor classes. You may not use `@AroundConstruct` methods within
the target class.

The `@AroundConstruct` method is called after dependency injection has
been completed for all interceptors associated with the target class.
The target class is created and the target class's constructor injection
is performed after all associated `@AroundConstruct` methods have called
the `Invocation.proceed` method. At that point, dependency injection for
the target class is completed, and then any `@PostConstruct` callback
methods are invoked.

`@AroundConstruct` methods can access the constructed target instance
after calling `Invocation.proceed` by calling the
`InvocationContext.getTarget` method.


[width="100%",cols="100%",]
|=======================================================================
a|
*Caution*:

Calling methods on the target instance from an `@AroundConstruct` method
is dangerous because dependency injection may not have completed on the
target instance.

|=======================================================================


`@AroundConstruct` methods must call `Invocation.proceed` in order to
create the target instance. If an `@AroundConstruct` method does not
call `Invocation.proceed`, the target instance will not be created.

[[GKHNI]]

[[using-multiple-lifecycle-callback-interceptors]]
Using Multiple Lifecycle Callback Interceptors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can define multiple lifecycle interceptors for a target class by
specifying the interceptor classes in the `@Interceptors` annotation:

[source,oac_no_warn]
----
@Interceptors({PrimaryInterceptor.class, SecondaryInterceptor.class,
        LastInterceptor.class})
@Stateless
public class OrderBean { ... }
----

Data stored in the `contextData` property of `InvocationContext` is not
sharable across different lifecycle events.

[[GKEDU]]

[[intercepting-timeout-events]]
Intercepting Timeout Events
~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can define interceptors for EJB timer service timeout methods by
using the `@AroundTimeout` annotation on methods in the target class or
in an interceptor class. Only one `@AroundTimeout` method per class is
allowed.

Timeout interceptors have the following form:

[source,oac_no_warn]
----
Object method-name(InvocationContext) throws Exception { ... }
----

For example:

[source,oac_no_warn]
----
@AroundTimeout
protected void timeoutInterceptorMethod(InvocationContext ctx) { ... }
----

Timeout interceptor methods can have public, private, protected, or
package-level access, and must not be declared static or final.

Timeout interceptors can call any component or resource callable by the
target timeout method, and are invoked in the same transaction and
security context as the target method.

Timeout interceptors may access the timer object associated with the
target timeout method through the `InvocationContext` instance's
`getTimer` method.

[[GKHLA]]

[[using-multiple-timeout-interceptors]]
Using Multiple Timeout Interceptors
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can define multiple timeout interceptors for a given target class by
specifying the interceptor classes containing `@AroundTimeout`
interceptor methods in an `@Interceptors` annotation at the class level.

If a target class specifies timeout interceptors in an interceptor
class, and also has an `@AroundTimeout` interceptor method within the
target class itself, the timeout interceptors in the interceptor classes
are called first, followed by the timeout interceptors defined in the
target class. For example, in the following example, assume that both
the `PrimaryInterceptor` and `SecondaryInterceptor` classes have timeout
interceptor methods:

[source,oac_no_warn]
----
@Interceptors({PrimaryInterceptor.class, SecondaryInterceptor.class})
@Stateful
public class OrderBean {
    ...
    @AroundTimeout
    private void last(InvocationContext ctx) { ... }
    ...
}
----

The timeout interceptor in `PrimaryInterceptor` will be called first,
followed by the timeout interceptor in `SecondaryInterceptor`, and
finally the `last` method defined in the target class.

[[sthref255]]

[[binding-interceptors-to-components]]
Binding Interceptors to Components
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Interceptor binding types are annotations that may be applied to
components to associate them with a particular interceptor. Interceptor
binding types are typically custom runtime annotation types that specify
the interceptor target. Use the `javax.interceptor.InterceptorBinding`
annotation on the custom annotation definition and specify the target by
using `@Target`, setting one or more of `TYPE` (class-level
interceptors), `METHOD` (method-level interceptors), `CONSTRUCTOR`
(around-construct interceptors), or any other valid target:

[source,oac_no_warn]
----
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Inherited
pubic @interface Logged { ... }
----

Interceptor binding types may also be applied to other interceptor
binding types:

[source,oac_no_warn]
----
@Logged
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
@Inherited
public @interface Secured { ... }
----

[[sthref256]]

[[declaring-the-interceptor-bindings-on-an-interceptor-class]]
Declaring the Interceptor Bindings on an Interceptor Class
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Annotate the interceptor class with the interceptor binding type and
`@Interceptor` to associate the interceptor binding with the interceptor
class:

[source,oac_no_warn]
----
@Logged
@Interceptor
public class LoggingInterceptor {
    @AroundInvoke
    public Object logInvocation(InvocationContext ctx) throws Exception { ... }
    ...
}
----

An interceptor class may declare multiple interceptor binding types, and
more than one interceptor class may declare an interceptor binding type.

If the interceptor class intercepts lifecycle callbacks, it can only
declare interceptor binding types with `Target(TYPE)`, or in the case of
`@AroundConstruct` lifecycle callbacks, `Target(CONSTRUCTOR)`.

[[sthref257]]

[[binding-a-component-to-an-interceptor]]
Binding a Component to an Interceptor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Add the interceptor binding type annotation to the target component's
class, method, or constructor. Interceptor binding types are applied
using the same rules as `@Interceptor` annotations:

[source,oac_no_warn]
----
@Logged
public class Message {
    ...
    @Secured
    public void getConfidentialMessage() { ... }
    ...
}
----

If the component has a class-level interceptor binding, it must not be
`final` or have any non-`static`, non-`private` `final` methods. If a
non-`static`, non-`private` method has an interceptor binding applied to
it, it must not be `final`, and the component class cannot be `final`.

[[sthref258]]

[[ordering-interceptors]]
Ordering Interceptors
~~~~~~~~~~~~~~~~~~~~~

The order in which multiple interceptors are invoked is determined by
the following rules.

* Default interceptors are defined in a deployment descriptor, and are
invoked first. They may specify the invocation order or override the
order specified using annotations. Default interceptors are invoked in
the order in which they are defined in the deployment descriptor.
* The order in which the interceptor classes are listed in the
`@Interceptors` annotation defines the order in which the interceptors
are invoked. Any `@Priority` settings for interceptors listed within an
`@Interceptors` annotation are ignored.
* If the interceptor class has superclasses, the interceptors defined on
the superclasses are invoked first, starting with the most general
superclass.
* Interceptor classes may set the priority of the interceptor methods by
setting a value within a `javax.annotation.Priority` annotation.
* After the interceptors defined within interceptor classes have been
invoked, the target class's constructor, around-invoke, or
around-timeout interceptors are invoked in the same order as the
interceptors within the `@Interceptors` annotation.
* If the target class has superclasses, any interceptors defined on the
superclasses are invoked first, starting with the most general
superclass.

The `@Priority` annotation requires an `int` value as an element. The
lower the number, the higher the priority of the associated interceptor.


[width="100%",cols="100%",]
|=======================================================================
a|
*Note*:

The invocation order of interceptors with the same priority value is
implementation-specific.

|=======================================================================


The `javax.interceptor.Interceptor.Priority` class defines the priority
constants listed in link:#BABFBAEF[Table 57-2].

[[sthref259]][[BABFBAEF]]




*Table 57-2 Interceptor Priority Constants*


[width="99%",cols="15%,15%,70%"]
|=======================================================================
|*Priority Constant* |*Value* |*Description*
|`PLATFORM_BEFORE` |0 |Interceptors defined by the Java EE Platform and
intended to be invoked early in the invocation chain should use the
range between `PLATFORM_BEFORE` and `LIBRARY_BEFORE`. These interceptors
have the highest priority.

|`LIBRARY_BEFORE` |1000 |Interceptors defined by extension libraries
that should be invoked early in the interceptor chain should use the
range between `LIBRARY_BEFORE` and `APPLICATION`.

|`APPLICATION` |2000 |Interceptors defined by applications should use
the range between `APPLICATION` and `LIBRARY_AFTER`.

|`LIBRARY_AFTER` |3000 |Low priority interceptors defined by extension
libraries should use the range between `LIBRARY_AFTER` and
`PLATFORM_AFTER`.

|`PLATFORM_AFTER` |4000 |Low priority interceptors defined by the Java
EE Platform should have values higher than `PLATFORM_AFTER`.
|=======================================================================



[width="100%",cols="100%",]
|=======================================================================
a|
Note:

Negative priority values are reserved by the Interceptors specification
for future use, and should not be used.

|=======================================================================


The following code snippet shows how to use the priority constants in an
application-defined interceptor:

[source,oac_no_warn]
----
@Interceptor
@Priority(Interceptor.Priority.APPLICATION+200
public class MyInterceptor { ... }
----
