история
Я думаю, что важно взглянуть на эволюцию Interceptors в Java EE из-за того простого факта, что он начинался как элемент, специфичный для EJB, а позже превратился в отдельную спецификацию, которая теперь открыта для расширения другими спецификациями Java EE.
Версия 1.0
Перехватчики были впервые представлены в EJB 3.0 (часть Java EE 5 ). У перехватчиков не было специальной спецификации, но они были версии 1.0 и купили базовые функции, связанные с AOP, для управляемых компонентов (POJO) с помощью простых аннотаций.
- @AroundInvoke — комментировать методы, содержащие логику перехвата для методов целевого класса
- @Intercerptors — связать классы-перехватчики с их целевыми классами / методами
- Возможность настройки перехватчиков для всего модуля (EJB JAR) через дескриптор развертывания
- @ExcludeDefaultInterceptors — чтобы отключить перехватчики по умолчанию, определенные в дескрипторе развертывания
- @ExcludeClassInterceptors — отключить глобально определенный перехватчик (на уровне класса) для определенного метода / конструктора класса
Перехватчики 1.1
Вместе с Java EE 6 с EJB 3.1 — перехватчики 1.1 все еще были включены в спецификацию EJB
- @InterceptorBinding — безопасный для типа способ указания перехватчиков класса или метода. Обратите внимание, что эта аннотация была использована CDI 1.0 (еще одна спецификация, представленная в Java EE 6), и ее подробности представлены в спецификации документа CDI 1.0, а не в EJB 3.1 (момент лампочки… по крайней мере, для меня)
- @Interceptor — Используется для явного объявления класса, содержащего логику перехвата в конкретном методе (аннотированном @AroundInvoke и т. Д.), В качестве перехватчика вместе с соответствующей привязкой перехватчика. Это также упоминалось только в документации CDI 1.0.
- @AroundTimeout — используется для перехвата тайм-аутов таймеров EJB вместе со способом получения экземпляра перехватываемого таймера (через javax.interceptor.InvocationContext.getTimer () )
Перехватчики 1.2
Перехватчики были разделены на отдельные спецификации в Java EE 7 и, таким образом, появились Interceptors 1.2.
- Interceptors 1.2 был техническим выпуском поверх 1.1, и, следовательно, номер JSR оставался таким же, как EJB 3.1 ( JSR 318 )
- Interceptor.Priority (статический класс) — для предоставления возможности определить порядок (приоритет), в котором должны вызываться перехватчики.
- @AroundConstruct — используется для перехвата конструирования целевого класса, то есть вызова логики до вызова конструктора целевого класса
Важно помнить, что Interceptors применимы к управляемым bean-компонентам в целом. Сами управляемые компоненты являются простыми объектами POJO, которые контейнер предоставляет привилегированные базовые сервисы — перехватчики являются одним из них наряду с обратными вызовами жизненного цикла, внедрением ресурсов.
Память Помощь
Полезно думать о Interceptors как о компонентах, которые могут вставляться в bean-компоненты на протяжении всего их жизненного цикла.
- прежде чем они даже построены — @AroundConstruct
- после того, как они построены — @PostConstruct
- в течение их жизни (вызов метода) — @AroundInvoke
- до уничтожения — @PreDestroy
- время ожидания EJB — @AroundTimeout
Давайте рассмотрим некоторые черты перехватчиков более подробно и попробуем ответить на такие вопросы, как
- где они применяются и что они перехватывают?
- как привязать перехватчики к цели (классу), которую они должны перехватить?
Типы перехватчиков (на основе перехваченного компонента)
Метод Перехватчики
- Достигается @AroundInvoke
public class MethodInterceptor{ @AroundInvoke public Object interceptorMethod(InvocationContext ictx) throws Exception{ //logic goes here } } @Stateless public class AnEJB{ @Interceptors(MethodInterceptor.class) public void bizMethod(){ //any calls to this method will be intercepted by MethodInterceptor.interceptorMethod() } }
- Метод, содержащий логику, может быть частью отдельного класса, а также самого целевого класса (класса, который должен быть перехвачен).
Перехватчики жизненного цикла
- Украсьте метод с помощью @AroundConstruct , чтобы перехватить вызов конструктора для класса
public class ConstructorInterceptor{ @AroundConstruct public Object interceptorMethod(InvocationContext ictx) throws Exception{ //logic goes here } } public class APOJO{ @Interceptors(ConstructorInterceptor.class) public APOJO(){ //any calls to this constructor will be intercepted by ConstructorInterceptor.interceptorMethod() } }
- Метод, аннотированный @AroundConstruct, не может быть частью перехваченного класса. Он должен быть определен с использованием отдельного класса Interceptor
- Use the @PostConstruct annotation on a method in order to intercept a call back method on a managed bean. Just to clarify again – the Interceptor spec does not define a new annotation as such. One needs to reuse the @PostConstruct (part of theCommon Annotations spec) on the interceptor method.
public class PostConstructInterceptor{ @PostConstruct public void interceptorMethod(InvocationContext ictx) throws Exception{ //logic goes here } } @Interceptors(PostConstructInterceptor.class) public class APOJO{ @PostConstruct public void bizMethod(){ //any calls to this method will be intercepted by PostConstructInterceptor.interceptorMethod() } }
- The @PreDestroy (another call back annotation defined in Common Annotations spec) annotation is used in a similar fashion
Time-out Interceptors
- As mentioned above – @AroundTimeout used to intercept time outs of EJB timers along with a way to obtain an instance of the Timer being intercepted (viajavax.interceptor.InvocationContext.getTimer())
Applying/Binding Interceptors
Using @Interceptors
- As shown in above examples – just use the @Interceptors annotation to specify the interceptor classes
- @Interceptors can be applied on a class level (automatically applicable to all the methods of a class), to a particular method or multiple methods and constructor in case of a constructor specific interceptor using @AroundConstruct
Using @IntercerptorBinding
- Interceptor Bindings (explained above) – Use @IntercerptorBinding annotation to define a binding annotation which is further used on the interceptor class as well as the target class (whose method, constructor etc needs to be intercepted)
@InterceptorBinding @Target({TYPE, METHOD, CONSTRUCTOR}) @Retention(RUNTIME) public @interface @Auditable { } @Auditable @Interceptor public class AuditInterceptor { @AroundInvoke public Object audit(InvocationContext ictx) throws Exception{ //logic goes here } } @Stateless @Auditable public class AnEJB{ public void bizMethod(){ //any calls to this method will be intercepted by AuditInterceptor.audit() } }
One can also use deployment descriptors to bind interceptors and target classes either in an explicit fashion as well as in override mode to annotations.
This was a rather quick overview of Java EE interceptors. Hopefully the right trigger for you to dig deeper ?
Cheers !