The Interceptors do what they say – they intercept on invocation and lifecycle events on an associated target class. They are used to implement cross-cutting concerns like logging and auditing. The Interceptors specification is extracted from the EJB specification into a new specification so that they can more generically applied to a broader set of specifications.
The CDI specification enhances the basic functionality by providing an annotation-based approach to binding interceptors to beans. The target class may specify multiple interceptors thus forming a chain of interceptors.
This section will explain how to add an interceptor that intercepts all the business method invocations and logs them.
Click on “Next>”.
This defines the interceptor binding type which is specified on the target class. This binding can have multiple implementations which can be enabled or disabled at deployment using beans.xml.
The generated binding consists of the following code:
@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logging {
}
@Interceptor
@Logging
public class LoggingInterceptor {
@AroundInvoke
public Object intercept(InvocationContext context) throws Exception {
System.out.println("BEFORE: " + context.getMethod());
Object result = context.proceed();
System.out.println("AFTER: " + context.getMethod());
return result;
}
}
Resolve the imports.
Notice the following points in the code:
- This class has the @Logging annotation which is the binding type generated earlier.
- It has the @Interceptor annotation marking this class to be an interceptor implementation.
- The @AroundInvoke annotation defines the method that will intercept the business method invocation on the target class and require the signature as shown in the code. An interceptor implementation cannot have more than one @AroundInvoke method.
- The InvocationContext parameter provides information about the intercepted invocation and provide operations to control the behavior of the chain invocation.
- This method prints a log message, with the name of the business method being invoked, before and after the business method execution.
Add the following fragment to beans.xml to enable the interceptor:
<interceptors>
<class>org.glassfish.samples.LoggingInterceptor</class>
</interceptors>
@Logging
This is the same binding type that we created earlier.
The interesting part is shown in the GlassFish log as shown:
It shows “BEFORE” and “AFTER” string along with the business method name and return type. These statements are printed from the interceptor implementation.