在spring框架中,当我们使用 @Async、@Transactional等注解时,一般都是加在class类的方法上面,并被另外一个class调用。而不会在同一个class中,使用this.xxx()去调用,如下代码:
public class A
{
@AutoWired
private B b;
public void sendMsg(String msg)
{
this.syncSendMsg(msg); // 异步不生效
b.syncSendMsg(msg); // 异步生效
}
@Async
public void syncSendMsg(String msg)
{
send(msg);
}
}
public class B
{
@Async
public void syncSendMsg(String msg)
{
send(msg);
}
public statc void main(String args[])
{
A a = spring.getBean(A.class); //伪代码,从spring中获取一个bean
a.sendMsg();
}
}
本文综合了以下几片文章,并结合自己的理解,一步步的来分析下为什么spring中的bean在this调用另外方法的时候会导致aop失效。
> 文章1:[https://blog.csdn.net/rylan11/article/details/76609643 spring事务失效那点事]
> 文章2:[Cglib invoke以及invokeSuper的一点区别](https://www.cnblogs.com/lvbinbin2yujie/p/10284316.html )
> 文章3:[https://my.oschina.net/guangshan/blog/1807721 详解Spring中Bean的this调用导致AOP失效的原因]
> 文章4:[https://my.oschina.net/guangshan/blog/1797461 完全读懂Spring框架之AOP实现原理]
一、JAVA代理机制
代理主要分为静态代理和动态代理:
动态代理:jdk动态代理和cglib动态代理
要注意到cglib代理中的proxy.invokeSuper(obj, args)和proxy.invoke(target, args)的区别。
二、spring代理机制
非接口的类使用的是cglib代理,实现了接口的类使用的是jdk动态代理
三、spring AOP实现
使用的是invoke(target,args), target表示的是目标对象,而不是代理对象