Adam Bien's Weblog

Monday Jul 20, 2009

Simplest Possible EJB 3.1 Interceptor

public class CallTracer {
    @AroundInvoke
    public Object transformReturn(InvocationContext context) throws Exception{
        System.out.println("---" + context.getMethod());
        return context.proceed();
    }
}

You can apply the interceptor now on the EJB class or its methods. The simplest way is to use annotations - but you can use XML as well.

@Stateless
@Interceptors(CallTracer.class)
public class HelloBean{
    public String sayHello(String message) {
        return "Echo from bean: " + message;
    }
}

How to compile:

You will need the the EJB 3.0 / 3.1 API in the classpath, or at least the @Interceptor annotation.

How to deploy:

Just JAR or WAR the interceptor with an EJB and put the archive into e.g: [glassfishv3]\glassfish\domains\domain1\autodeploy

Btw. the deployment of the WAR took on my machine:


INFO: Loading application LeanestInterceptor at /LeanestInterceptor
INFO: Deployment of LeanestInterceptor done is 298 ms

How to use:

e.g.:

public class HelloInterceptor extends HttpServlet {
   
    @EJB
    private HelloBean helloBean;

//.... 

}

And: there is no XML, strange configuration, libraries, additional dependencies needed... EJB 3 interceptors will run on >10 appservers. You will find the whole executable project (tested with Netbeans 6.7 and Glassfish v3 preview) in: http://kenai.com/projects/javaee-patterns/ [project name: LeanestInterceptor].

[See also "Real World Java EE Patterns - Rethinking Best Practices", page 42] 


NEW: Java EE 7 Testing and Quality Workshop

A book about rethinking Java EE Patterns

Comments:

Hello,

Thanks for this simple example.

As the interceptor is declared at the class level, I infer it will be used for each method.

Is there an annotation to prevent an (or all) interceptor(s) to be fired on a specific method ?

Except code testing the InvocationContext.getMethod result in the interceptor itself.

Thanks

Wadaël

Posted by Wadael on July 20, 2009 at 04:08 PM CEST #

Hi Wadael,

sure no problem:

@ExcludeClassInterceptors
public String dontInterceptMePlease(){
return "hello";
}

I just extended the example and pushed it into kenai: http://kenai.com/projects/javaee-patterns/.

You can apply the @Interceptor annotation on methods as well...

thanks for the nice comment!,

adam

Posted by Adam Bien on July 20, 2009 at 04:26 PM CEST #

Do you actually know how expensive this is at runtime?

Put this on the wrong methods and you can very easily slowdown a system and that is before you have even done anything with the context itself. Unless of course the existing infrastructure is already slow in creating this context (irrespective of interceptors presence) and the methods themselves are slow.

I have come across a few applications which have used this very liberally resulting in huge call stacks (hint: lots of xxx->proceeds->xxx->proceed) and lots of wasted processing cycles before doing any real work.

Not sure why the spec also limited the interceptors to the deployment module itself.

Maybe I am being a bit overly cautious here as I generally measure in nanoseconds whereas most others are still thinking in ms level timing.

Posted by William Louth on July 22, 2009 at 03:14 PM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
realworldpatterns.com
...the last 150 posts
...the last 10 comments
Links
License