New Interceptor Configuration in Seam 2.1.x
Wednesday, August 27th, 2008I thought this is a good time for this post since Seam 2.1.0b1 is out. If you look through the feature list for 2.1.0b1, you’ll notice the new built-in ability to customize the default interceptor stack which I find convenient. Lately, I have been wanting to enable or disable my custom Interceptors at deployment time but realized this wasn’t easily achievable in 2.0.x. If you know of a way, let me know. The 2.1.x releases seem to support this feature, although I haven’t seen it documented. Interceptors in 2.1.x can take an optional method with the signature public boolean isInterceptorEnabled() {} where it will be checked at deployment time whether the interceptor is enabled or disabled for that particular component. This gives you finer control on when interceptors will be enabled against your components because they can be source of performance headaches in Seam applications.
Here’s a contrived example where we have a SimpleProfile annotation that is used to mark components to use the ProfileInterceptor which simply tracks the response time for each invocation call to the component.
// SimpleProfile.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Interceptors(ProfileInterceptor.class)
public @interface SimpleProfile{}
// ProfilerInterceptor.java
@Interceptor
public class ProfileInterceptor extends AbstractInterceptor {
private static LogProvider log
= Logging.getLogProvider(ProfileInterceptor.class)
@AroundInvoke
public Object aroundInvoke(InvocationContext ivc) throws Exception {
long begin = System.currentTimeMillis();
Object result = ivc.proceed();
long total = System.currentTimeMillis() - begin;
Method method = ivc.getMethod();
log.debug(method.getDeclaringClass().getSimpleName()
+ "." + method.getName() + " - " + total + "ms")
return result;
}
public boolean isInterceptorEnabled() {
return getComponent().beanClassHasAnnotation(SimpleProfile.class)
&& Init.instance().isDebug();
}
}
Now, if we have a Seam component:
@Name("exampleBean") @SimpleProfile public class ExampleBean {}
the interceptor will see the presence of the annotation and then check whether the debug property for Seam’s Init instance is turned on. This property is configurable in the components.xml so we can easily enable or disable Seam Interceptors at deployment time.
As a side note, you can customize the default list of Seam interceptors that will be used in the application by overriding the Init default property in components.xml:
<core:init>
<core:interceptors>
..
<value>your.package.SomeInterceptor</value>
<value>your.package.AnotherInterceptor</value>
..
</core:interceptors>
</core:init>