January 9, 2015

The Java EE 6 Interceptors

Introduction

The AOP Interceptor was in EE 6 introduced and was before only supported with additional libraries such as aspectj and jboss-aop.

Before using Interceptor one should first really consider if this is the right tool for solving ones problem. Because using AOP Interceptor is not a holy grail, BUT for certain problem it is. Those are:

  • Logging
  • Caching
  • Security
  • And similiar

The above examples are so called cross cutting concern, that are well suited to be solved with AOP Interceptor.

Java EE 6 Interceptors

To create a Java EE Interceptor you create a POJO with:

  • A public, no-argument constructor.
  • One around-invoke interceptor method with syntax @javax.interceptor.AroundInvoke visibility Object method-name(javax.interceptor.InvocationContext) throws Exception { ... }

Example

public class AuditInterceptor {

    private java.util.logging.Logger log = java.util.logging.Logger
            .getLogger(AuditInterceptor.class.getName());

    @javax.interceptor.AroundInvoke
    protected Object invoke(javax.interceptor.InvocationContext ctx)
            throws Exception {

        StringBuilder sb = new StringBuilder("[");
        for (Object obj : ctx.getParameters()) {
            sb.append(obj.toString());
            sb.append(", ");
        }
        sb.append("]");
        log.log(java.util.logging.Level.INFO,
                "user {0} invoced {1} with method {2} and parameters: {3}",
                new Object[] { ctx.getTarget().toString(), 
                        ctx.getMethod().getName(), sb.toString() });
        return ctx.proceed();
    }
}

To use it, add @javax.interceptor.Interceptors(AuditInterceptor.class) to any bean that supports injection, e.g. Servlet, JSF ManagedBean, EJB.

Example

@javax.interceptor.Interceptors(AuditInterceptor.class)
@javax.ejb.Stateless
public class FooSLSB {

    public void save(Object obj) {
        // do something
    }
}

NOTE: You can either annotate the class (Interceptor will be called whenever every public method is called) or a specific method.

The final piece to make it work is to add the beans.xml in:

  • META-INF/ for ejb jar.
  • WEB-INF/ for web war.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">

</beans>

Reference

Oracle EE 6 Tutorial Chapter 50: Using Java EE Interceptors