Java Platform, Enterprise Edition (Java EE) 8
Учебник по Java EE

Назад Вперёд Содержание

Использование Interceptor-ов в приложениях CDI

Interceptor — это класс, используемый для вставки в вызовы методов или события жизненного цикла, которые происходят в связанном целевом классе. Interceptor выполняет такие задачи, как ведение журнала или аудит, которые отделены от бизнес-логики приложения и часто повторяются в приложении. Такие задачи часто называют сквозными задачами. Interceptor-ы позволяют указывать код этих задач в одном месте для удобства сопровождения. Когда Interceptor-ы были впервые представлены в Java EE, они были характерны для Enterprise-бинов. В платформе Java EE их можно использовать с управляемыми объектами Java EE всех видов, включая Managed-бины.

Для получения информации об Interceptor-ах Java EE см. главу 57 «Использование Interceptor-ов Java EE».

Класс Interceptor-а часто содержит аннотированный метод @AroundInvoke, который определяет задачи, которые Interceptor будет выполнять при вызове перехваченных методов. Он также может содержать метод, аннотированный @PostConstruct, @PreDestroy, @PrePassivate или @PostActivate, чтобы указать Callback-метод жизненного цикла Interceptor-а и метод, аннотированный @AroundTimeout, для указания Interceptor-ов тайм-аута EJB. Класс Interceptor-а может содержать более одного метода Interceptor-а, но он должен иметь не более одного метода каждого типа.

Наряду с Interceptor-ом приложение определяет один или несколько типов привязки Interceptor-а, которые представляют собой аннотации, которые связывают Interceptor с целевыми компонентами или методами. Например, пример billpayment содержит Interceptor, аннотированный @Logged, и Interceptor с именем LoggedInterceptor. Объявление типа привязки Interceptor-а выглядит примерно как объявление квалификатора, но оно аннотируется с помощью javax.interceptor.InterceptorBinding:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logged {
}

Привязка Interceptor-а также имеет аннотацию java.lang.annotation.Inherited, чтобы указать, что аннотация может быть унаследована от родительских классов. Аннотация @Inherited также применяется к пользовательским областям видимости (не обсуждаемым в этом руководстве), но не относится к квалификаторам.

Тип привязки Interceptor-а может объявлять другие привязки Interceptor-а.

Класс Interceptor-а аннотируется привязкой Interceptor-а, а также аннотацией @Interceptor. Пример см. в разделе Класс Interceptor-а LoggedInterceptor.

Каждый метод @AroundInvoke принимает аргумент javax.interceptor.InvocationContext, возвращает java.lang.Object и допускает исключение Exception. Он может вызывать методы InvocationContext. Метод @AroundInvoke должен вызывать метод continue, который вызывает метод целевого класса.

После того как Interceptor и тип привязки определены, вы можете аннотировать бины и отдельные методы с помощью типа привязки, чтобы указать, что Interceptor должен вызываться либо для всех методов компонента, либо для конкретных методов. Например, в примере billpayment бин PaymentHandler аннотируется @Logged, что означает, что любой вызов его бизнес-методов вызовет метод @AroundInvoke Interceptor-а:

@Logged
@SessionScoped
public class PaymentHandler implements Serializable {...}

Однако в компоненте PaymentBean только методы pay и reset имеют аннотацию @Logged, поэтому Interceptor вызывается только тогда, когда эти методы вызываются:

@Logged
public String pay() {...}

@Logged
public void reset() {...}

Чтобы Interceptor вызывался в приложении CDI, он, как альтернатива, должен быть указан в файле beans.xml. Например, класс LoggedInterceptor указан следующим образом:

<interceptors>
    <class>javaeetutorial.billpayment.interceptors.LoggedInterceptor</class>
</interceptors>

Если приложение использует более одного Interceptor-а, они вызываются в порядке, указанном в файле beans.xml.

Interceptor-ы, указанные в файле beans.xml, применяются только к классам в одном и том же архиве. Используйте аннотацию @Priority, чтобы глобально указать Interceptor-ы для приложения, состоящего из нескольких модулей, как в следующем примере:

@Logged
@Interceptor
@Priority(Interceptor.Priority.APPLICATION)
public class LoggedInterceptor implements Serializable { ... }

Interceptor-ы с более низкими значениями приоритета вызываются первыми. Не обязательно указывать Interceptor в файле beans.xml, когда используется аннотация @Priority.


Назад Вперёд Содержание
Логотип Oracle  Copyright © 2017, Oracle и/или её дочерних компаний. Все права защищены. Версия перевода 1.0.5 (Java EE Tutorial — русскоязычная версия)