Spring Aop嵌套调用时没有生效

转载自:https://blog.csdn.net/hong10086/article/details/78424481

  Spring AOP在同一个类里自身方法相互调用时是无法拦截的。比如在一个 Service 类的 doSomething1() 方法中通过doSomething2(); 语句调用了同一个类中的 doSomething2 方法,运行时通过调试发现 doSomething1 方法的执行前后正常地执行了自定义的 around advice,但是在 doSomething2 方法执行前后并未如期望的那样执行自定义的 around advice。原因呢?
  Spring的代理实现有两种:一是基于 JDK Dynamic Proxy 技术而实现的;二是基于CGLIB 技术而实现的。来基于JDK Dynamic Proxy 的动态代理看下Spring AOP怎么弄的。

代码如下:

public interface ICustomerService {  
    public void doSomething1();  
    public void doSomething2();  
}  
 public class CustomerServiceImpl implements ICustomerService {  
  
    public void doSomething1() {  
        System.out.println("Inside CustomerServiceImpl.doSomething1()");  
        doSomething2();  
    }  
  
    public void doSomething2() {  
        System.out.println("Inside CustomerServiceImpl.doSomething2()");  
    }  
}  

  下面来模拟动态生成代理类的过程,若使用 JDK Dynamic Proxy,这一过程是在运行时进行的。CustomerServiceImpl 类对象的代理类:

 public class CustomerServiceProxy implements ICustomerService {  
  
    private ICustomerService customerService;  
  
    public void setCustomerService(ICustomerService customerService) {  
        this.customerService = customerService;  
    }  
  
    public void doSomething1() {  
        doBefore();  
        customerService.doSomething1();  
        doAfter();  
    }  
  
    public void doSomething2() {  
        doBefore();  
        customerService.doSomething2();  
        doAfter();  
    }  
  
    private void doBefore() {  
        // 例如,可以在此处开启事务  
        System.out.println("do some important things before...");  
    }  
  
    private void doAfter() {  
        // 例如,可以在此处提交或回滚事务、释放资源等等  
        System.out.println("do some important things after...");  
    }  
}  

  Spring实际上是在容器中生成了CustomerServiceProxy,将原始的CustomerServiceImpl设置到了CustomerServiceProxy中。
  doSomething1()中调用doSomething2()方法,它隐含的意思是this.doSomething2(),在CustomerServiceImpl类中 this关键字表示的是当前这个CustomerServiceImpl类的实例。那程序会去执行 CustomerServiceImpl 类中的 doSomething2() 方法了,而不会去执行 CustomerServiceProxy 类中的 doSomething2()方法。
  在使用 Spring AOP 的时候,从 IOC 容器中获取的 Service Bean 对象其实都是代理对象,而不是那些 Service Bean 对象本身,也就是说获取的并不是被代理对象或代理目标。当在Service 类中使用 this 关键字嵌套调用同类中的其他方法时,由于 this 关键字引用的并不是该 Service Bean 对象的代理对象,而是其本身,故 Spring AOP 是不能拦截到这些被嵌套调用的方法的。

  怎么解呢?参考 https://blog.csdn.net/huangjinlong77/article/details/42707571

猜你喜欢

转载自blog.csdn.net/zero__007/article/details/85925960