-
Notifications
You must be signed in to change notification settings - Fork 0
2. Interceptors
Interceptors fall in four categories
- Lifecycle callback interceptor (@PostConstruct, @PreDestroy, @AroundConstruct)
- Business Method interceptor (@AroundInvoke)
- Time-out method interceptor (@AroundTimeout)
Eg:
@AroundInvoke
<access modifier> Object <method name>(InvocationContext ic) throws Exception;
The method(s) marked with any of the above annotations should obey the below conditions:
- It can have any access level modifier but should not be static and/or final.
- Must have InvocationContext parameter
- Can throw a checked exception.
- The lifecycle interceoptor methods must have void return type but other types(@AroundInvoke, @AroundTimeout) Must return Object, which is the result of invoked target method.
Interceptors – For chaining one or more interceptors to the target class.
ExcludeClassInterceptors – Excludes method(s) from the interceptors declared at the class level.
InterceptorBinding – Binds the interceptor class(es) with intercepted class.
Interceptor - This annotation attaches the InterceptorBinding to the interceptor
Priority – Prioritizes the order of interceptor methods order.
Ways of adding interceptor
-
This is the simplest way of adding interceptor to the bean.
A bean can annotate its methods with any of the 4 categories listed at the beginning.
The scope of this interceptor is limited to the bean itself.
Notice that this class doesn't need any additional annotation at the class level.
Eg:
public class BookOrderService {
public void createOrder(Order order) {
//logic
}
@AroundInvoke
private Object logMethod(InvocationContext ic) throws Exception {
logger.info("Entering");
try {
ic.proceed();
} finally {
logger.info("Existing");
}
}
}
In the above example, the logMethod() will be triggered when container makes call to any of the methods(ie. createOrder() method) in BookOrderService.java.
-
In this approach, the cross cutting functionality will be isolated into a class and instruct the container to intercept the calls on several beans using @Interceptors annotation.
Eg:
@Interceptors(MyInterceptor1.class, MyInterceptor2.class)
public class BookOrderService {
@Interceptors(MyInterceptor3.class, MyInterceptor4.class)
public void createOrder(Order order) {
//logic
}
public void updateOrder(Order order) {
//logic
}
}
Notice that the order the listed interceptors get executed, is the order they are listed. In this example, MyInterceptor1 will be executed before MyInterceptor2 for updateOrder() and the sequence is MyInterceptor1, MyInterceptor2, MyInterceptor3 and MyInterceptor4 for createOrder()
InterceptorBinding introduces a level of indirection and loose coupling for interceptors. Notice that the @InterceptorBinding is applicable only for CDI enabled beans.
To make use of interceptor binding, one should
-
a. define a InterceptorBinding annotation.
Eg:
@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Monitord{}
-
b. Attach the InterceptorBinding annotation to the interceoptor itself. This can be done by annotating the interceoptor with both @Interceptor and interceptorbinding.
Eg:
@Interceptor
@Monitord
public class MyInterceptor {
@AroundInvoke
public Object method(InvocationContext ic) throws Exception {
//logic
}
}
-
c. Annotate the desired bean or bean method with the interceoptorbinding.
Eg:
@Monitord
public class BookOrderService {
method()
}
public class BookSupplyService {
@Monitord
method()
}