EJB3 provides a standard interceptor model. Most of the examples I've seen use simple reflection on the name of the method to determine whether or not to apply an interceptor.
Having seen the power of annotation-drive AOP in JBoss AOP, I knew there was a better way. Annotations are an absolutely brilliant way of specifying a pointcut. It's much better than the wacky pointcut expressions you see, and it certainly beats hardcoding method names in your interceptor.
I wasn't sure how much work it would be, so I decided to put together a simple example to try it out. It turns out to be even easier than I thought. The most difficult part is defining the annotation. Here's one I put together as a test:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) public @interface TimedMethod
{
}
Note RetentionPolicy.RUNTIME, which makes sure the annotation stays on the class and can be queried at runtime. ElementType.METHOD means the annotation can be applied to any method, like this:
@TimedMethod publicList<Product> getRecentHistory(Customer customer, int howmany) { // ... }
The idea is that I can add or remove the @TimedMethod annotation to change whether or not the method is timed. The interceptor that uses the annotation is easy to write:
One line of Java code is all that is needed to test for the presence of the annotation. It all works. In this example, I've assumed the interceptor method will be on the bean itself, but more than likely it would be in it's own class and linked with an @Interceptor(TimedMethodInterceptor.class) annotation on the class.
You might be wondering about the utility of this. If I have to recompile and redeploy to bring in the annotation, what is the point? The redeploy isn't actually
that bad. Building EJB3 projects is very fast if you don't complicate your build, and JBoss is very fast at redeploying apps. You don't have to lose your HTTP session on reploy, so for all practical purposes you should be able to update the annotations between clicks in a web app without noticing anything.
I did while testing out a recent web application. "Oh, that's a bit slow." I added the annotation, built and deployed. 10 seconds later I reloaded the web page and there was my timing information. It's not instantaneous, but it's pretty good response time for a change.
Getting back to the original topic of annotation-drive interceptors, give it a shot if you've written off EJB3 interceptors as uninteresting. I think you'll be pleasantly surprised.