Preloader image

The rules here are pretty hard to follow without examples.

When they say one AroundInvoke per class they mean that in the most literal sense as in one individual java class definition, not including it’s parent class or classes, may exactly one AroundInvoke method. The bean or interceptor class may have an AroundInvoke method, its parent class may have an AroundInvoke method, the parent’s parent class may have an AroundInvoke method and so on.

So the following is legal.

public class Plant {
    @AroundInvoke
    public Object a(InvocationContext ctx) throws Exception {
        return ctx.proceed();
    }
}

public class Fruit extends Plant {
    @AroundInvoke
    public Object b(InvocationContext ctx) throws Exception {
        return ctx.proceed();
    }
}

@Stateless
public class Apple extends Fruit implements AppleLocal {
    @AroundInvoke
    public Object c(InvocationContext ctx) throws Exception {
        return ctx.proceed();
    }

    public String grow(){
        return "ready to pick";
    }
}

public interface AppleLocal {
    public String grow();
}

The result is that when the "grow" method on AppleLocal (and consequently on Apple) is invoked, the container will first invoke the following AroundInvoke methods in this order; a, b, c.

What the ejb spec doesn’t do such a good job at stating is that there are ways to effectively shut off the callbacks, including AroundInvoke, of a parent class by simply overriding the method. We can shut off the "a" around invoke with a slightly different version of Apple as follows:

@Stateless
public class Apple extends Fruit implements AppleLocal {

    // This will now never be called.
    public Object a(InvocationContext ctx) throws Exception {
        return null;
    }

    @AroundInvoke
    public Object c(InvocationContext ctx) throws Exception {
        return ctx.proceed();
    }

    public String grow(){
        return "ready to pick";
    }
}

The result of this is that when the "grow" method on AppleLocal is invoked, the container will first invoke the AroundInvoke methods "b" then "c" skipping "a" completely.

When they say that an AroundInvoke method cannot be a business method, they mean that they cannot be exposed to clients through a local or remote interface. The following would be illegal.

public interface AppleLocal {
    public String grow();

    // This is an AroundInvoke method in the bean class, not a legal business method!
    public Object c(InvocationContext ctx) throws Exception;
}