Question about interceptors
ron_sigal Jul 23, 2012 5:53 PMHi,
I wrote a test for Resteasy in which interceptors are applied by way of 1) @Interceptors and 2) CDI annotations, and I've gotten what looks like an anomalous behavior. As I understand the specs, the following rules apply:
1. Interceptors applied by way of @Interceptors are ordered by the rules
a) class interceptors execute before method interceptors
b) within each category, interceptors are ordered by their order in the @Interceptor annotation (or the xml file)
2. Interceptors applied by way of CDI annotations are ordered according to their order in beans.xml, regardless of their placement on class or method.
3. According to the CDI spec, "Interceptors declared using @Interceptors or in ejb-jar.xml are called before interceptors using interceptor bindings.
I have an interceptor binding
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface TestBinding
{
String placement() default "CLASS";
}
My JAX-RS resource looks like
@Path("/")
@RequestScoped
@Interceptors ({Interceptor0.class})
@TestBinding(placement="CLASS")
public class InterceptorResource
{
@Inject private Logger log;
@POST
@Path("test")
@Interceptors ({Interceptor1.class})
@TestBinding(placement="METHOD")
public Response test()
{ ...
My interceptors, somewhat abbreviated, are
public class Interceptor0
{
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception
{
log.info("*** Intercepting call to Interceptor0.intercept()");
Object result = ctx.proceed();
return result;
}
}
public class Interceptor1
{
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception
{
log.info("*** Intercepting call to Interceptor1.intercept()");
Object result = ctx.proceed();
return result;
}
}
@Interceptor
@TestBinding(placement="CLASS")
public class Interceptor2
{
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception
{
log.info("*** Intercepting call to Interceptor2.intercept()");
Object result = ctx.proceed();
return result;
}
}
@Interceptor
@TestBinding(placement="METHOD")
public class Interceptor3
{
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception
{
log.info("*** Intercepting call to Interceptor3.intercept()");
Object result = ctx.proceed();
return result;
}
}
and beans.xml is
<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">
<interceptors>
<class>org.jboss.resteasy.cdi.interceptors.Interceptor2</class>
<class>org.jboss.resteasy.cdi.interceptors.Interceptor3</class>
</interceptors>
</beans>
So, Interceptor0 and Interceptor1 are applied by way of the @Interceptors annotation, and Interceptor2 and Interceptor3 are applied by way of the @TestBinding annotation. The output includes
16:40:59,606 INFO [org.jboss.resteasy.cdi.interceptors.Interceptor0] (http--127.0.0.1-8080-3) *** Intercepting call to Interceptor0.intercept()
16:40:59,606 INFO [org.jboss.resteasy.cdi.interceptors.Interceptor2] (http--127.0.0.1-8080-3) *** Intercepting call to Interceptor2.intercept()
16:40:59,607 INFO [org.jboss.resteasy.cdi.interceptors.Interceptor3] (http--127.0.0.1-8080-3) *** Intercepting call to Interceptor3.intercept()
16:40:59,607 INFO [org.jboss.resteasy.cdi.interceptors.Interceptor1] (http--127.0.0.1-8080-3) *** Intercepting call to Interceptor1.intercept()
Some of this ordering makes sense:
* Interceptor0 appears before Interceptor1 by rule 1a above.
* Interceptor2 appears before Interceptor3 by rule 2 above.
But the appearance of Interceptor2 and Interceptor3 before Interceptor1 seems to violate rule 3. I expected them to be ordered: Interceptor0, Interceptor1, Interceptor2, Interceptor3.
Am I missing something? Have I done something wrong?
Thanks,
Ron
-
resteasy-cdi-ejb-test.tgz 38.2 KB