spring aop类方法之间调用切面不能匹配

参考:https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#aop-understanding-aop-proxies

public class SimplePojo implements Pojo {

    public void foo() {
        // this next method invocation is a direct call on the 'this' reference
        this.bar();
    }

    public void bar() {
        // some logic...
    }
}

你会发现foo方法调用的bar方法并没有织入对应的增强。

原因分析:

AOP的本质是:通过创建新的代理对象,在代理对象里面添加对应的增强代码实现。完成代理对象的调用,即完成了增强的过程。

public class SimplePojoProxy implements Pojo {
   Pojo pojo;
  
    public void foo() {
        before();
		pojo.foo();
        after();
    }

    public void bar() {
        before();
		pojo.bar();
        after();
    }
}

如上,SimplePojoProxy代理对象调用foo方法,切入了对应的增强,但是在foo方法调用bar方法的时候,其实是针对pojo也就是目标对象发生调用的(目标对象方法中并没有对应的增强),而非SimplePojoProxy代理的bar方法,所以导致增强失效。

spring aop类方法之间调用切面不能匹配_第1张图片

解决方案1:

注意:使用这种方式必须设置aop-config标签的expose-proxy属性为true,具体原理请参考AOPUtils分析

public class SimplePojo implements Pojo {

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

    public void bar() {
        // some logic...
    }
}

解决方案2

public class Main {

    public static void main(String[] args) {

        ProxyFactory factory = new ProxyFactory(new SimplePojo());
        factory.adddInterface(Pojo.class);
        factory.addAdvice(new RetryAdvice());
        factory.setExposeProxy(true);

        Pojo pojo = (Pojo) factory.getProxy();

        // this is a method call on the proxy!
        pojo.foo();
    }
}

你可能感兴趣的:(Java,spring)