参考: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方法,所以导致增强失效。
解决方案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();
}
}
解决方案3
通过beanFactory获取到代理对象,调用对应方法。