最近在开发导入的功能,因为要获取导入进度条,所以要将原本同步导入改成异步的。由于对Spring的理解较少,在使用时是直接在同一个类中,一个方法调用了另一个有@Async的注解的方法,导致异步死活没有生效。下面是我解决后的一些自己的理解。
在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的。
spring在项目启动时会对bean中的类进行实例化,并扫描其中的方法是否含有@Async的注解,若有注解,会生成一个子类(代理类),在这个代理类中,会先开辟一个新线程去执行这个方法。如果这个方法是被其他方法调用的,那样的话并不会经过代理类。意思是说,@Async注解的效果是在代理类中执行的,但是如果是同一个类中,代理类中会调用原类的方法,而原类的方法再调的有@Async注解的原类中的该方法,是并没有通过代理类的。所以注解并没有执行。这样说可能会有点绕,写段代码吧。
@Service
class A{
@Async
method b(){...}
method a(){ //标记1
b();
}
}
//Spring扫描注解后,创建了另外一个代理类,并为有注解的方法插入一个类似createThread()创建新线程的方法:
class proxy$A{
A objectA =new A();
method b(){
createThread();
objectA.b();
}
method a(){
objectA.a();//由于a()没有注解,所以不会启动transaction,而是直接调用A的实例的a()方法
}
}
原文链接:https://blog.csdn.net/ClementAD/article/details/47339519