Spring AOP not working, when the method is called internally within a bean

后端 未结 3 2069
轻奢々
轻奢々 2020-11-29 09:36

I have several Aspects coded in my application. All others works except for the following.

Service Interface

package com.enbiso.proj         


        
相关标签:
3条回答
  • 2020-11-29 10:15

    I guess the problem is the @args condition.

    Spring documentation states the following:

    @args - limits matching to join points (the execution of methods when using Spring AOP) where the runtime type of the actual arguments passed have annotations of the given type(s) 
    

    Therefore the parameter of @args has to be a type expression. So the correct pointcut expression is

    @AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(..)) && args(com.enbiso.proj.estudo.system.service.impl.Message")
    

    or simply

    @AfterReturning(value = "execution(* com.enbiso.proj.estudo.system.service.impl.MessageServiceImpl.send(com.enbiso.proj.estudo.system.service.impl.Message))")
    

    Please adjust the package of Message if it doesn't fit.

    0 讨论(0)
  • 2020-11-29 10:19

    You are running into a limitation of Spring AOP on self-invocation. You basically can get around it by using AopContext.currentProxy(), refactor code into different beans, or use full ApsectJ weaving.

    See explanation here and workaround(s). http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies

    0 讨论(0)
  • 2020-11-29 10:40

    Thank you jst for clearing the things up. Just for the information purposes for the future developer in SO, I'm posting the full answer to this question


    Lets assume that there is a bean from SimplePojo

    public class SimplePojo implements Pojo {
        public void foo() {
            this.bar();
        }
        public void bar() {
            ...
        }
    }
    

    When we call the method foo(), it reinvokes the method bar() inside it. Even thought the method foo() is invoked from the AOP Proxy, the internal invocation of the bar() is not covered by the AOP Proxy.

    Proxy calls

    So eventually this makes, if there are any advices attached to the method bar() to not get invoked

    Solution

    Use AopContext.currentProxy() to call the method. Unfortunately this couples the logic with AOP.

    public void foo() {
       ((Pojo) AopContext.currentProxy()).bar();
    }
    

    Reference:

    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies

    0 讨论(0)
提交回复
热议问题