9 Replies Latest reply: Oct 11, 2010 3:37 AM by dapeng liu RSS

Interceptor is not invoked within same bean

dapeng liu Newbie

i have implemented a very simple LogAccess interceptor, which i want to record the method invocations.


codes below. when i call the m1(), i only got the m1 logged, not m2 ...


so is this the limitation of the CDI interceptor impl ?


glassfish 3.0.1 opensource edition


@Stateless
public class MyBean {

    @LogAccess
    public String m1() {
        return m2();
    }

    @LogAccess
    public String m2() {
        return "hello world";
    }
}

@LogAccess
@Interceptor
public class LogAccessInterceptor {
    Logger logger = Logger.getLogger("LogAccess");
    @AroundInvoke
    public Object logAccess(InvocationContext ic) throws Exception {
        logger.info(ic.getMethod().toString());
        return ic.proceed();
    }
}

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface LogAccess {
}







  • 1. Re: Interceptor is not invoked within same bean
    Cloves Almeida Newbie

    This is the correct behavior as in the CDI spec. Only methods called by client classes are considered business methods and, thus, are intercepted.

  • 2. Re: Interceptor is not invoked within same bean
    nimo stephan Master

    when i call the m1(), i only got the m1 logged, not m2 ...

    If you want to call m2 when calling m1, then you can use a CDI-Event.


    If you want to trigger more than one interceptors within one method invocation, then you can use standard ejb annotation:


    @Interceptors(A.class, B.class)
    public Customer m1()

  • 3. Re: Interceptor is not invoked within same bean
    Jan Groth Novice

    Cloves Almeida wrote on Oct 04, 2010 19:17:


    This is the correct behavior as in the CDI spec. Only methods called by client classes are considered business methods and, thus, are intercepted.


    I don't get this. What does that imply for the above snippet? That this code does not contain any business-methods? Certainly a client (whatever that is in the sense of the spec) can call both methods, can't it?


  • 4. Re: Interceptor is not invoked within same bean
    Jan Groth Novice

    nimo mayr wrote on Oct 05, 2010 05:45:


    when i call the m1(), i only got the m1 logged, not m2 ...

    If you want to call m2 when calling m1, then you can use a CDI-Event.

    If you want to trigger more than one interceptors within one method invocation, then you can use standard ejb annotation:

    @Interceptors(A.class, B.class)
    public Customer m1()


    I'd recommend to raise the interceptor to class level, and check each method invocation. You'll find a very helpful class AnnotationUtils in SEAM-FACES, which provides an isAnnotationPresent(class clazz) method.

  • 5. Re: Interceptor is not invoked within same bean
    dapeng liu Newbie

    could you please elaborate more ?



    i change to




    @LogAccess
    @Stateless
    public class MyBean {
    
        public String m1() {
            return m2();
        }
    
        public String m2() {
            return "hello world";
        }
    }




    but i getitng the same result as only m1 is logged, m2 is not





  • 6. Re: Interceptor is not invoked within same bean
    Jan Groth Novice

    Dapeng,


    my idea is to raise the interceptor-binding to class level, and make the interceptor intercept each method call. in the interceptor itself you then have to check for the presence of a certain annotation, just like this:


    
    @LogAccess
    @Interceptor
    public class TaskInterceptor implements Serializable {
    
    @AroundInvoke
         public Object around(final InvocationContext ctx) throws Exception {
    
              if (Annotations.isAnnotationPresent(ctx.getMethod(), LogAccess.class)) {
                        ...
              }
              return ctx.proceed();
         }
    



    I would expect this to work, but as I stated earlier: I'm not sure about the intention of the spec in this case.

  • 7. Re: Interceptor is not invoked within same bean
    Jan Groth Novice

    btw, just to doublecheck: can you confirm that you are call both methods from outside of your bean? the interceptor is not expected to work for internal calls....

  • 8. Re: Interceptor is not invoked within same bean
    Jan Groth Novice

    good morning to myself


    ;-)



    i overlooked the fact that you are calling m2 from within m1.


    what cloves almeida posts is absolutely correct - only external calls are intercepted, no internal calls.



  • 9. Re: Interceptor is not invoked within same bean
    dapeng liu Newbie

    thank you guys for your help