在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的。
原因:
spring 在扫描bean的时候会扫描方法上是否包含@Async注解,如果包含,spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean的。此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,@Async注解就无效了。
例如:
@Service
class A{
@Async
method b(){
System.out.println("我是b");
}
method a(){
System.out.println("我是a");
b();
}
}
//Spring扫描注解后,创建了另外一个代理类:
class proxy$A{
A objectA = new A();
method b(){
async();
objectA.b();
}
method a(){
objectA.a();
}
}
当我们调用A的bean的b()方法的时候,被proxy$A
拦截后,执行proxy$A.b()
,异步生效。
当我们调用A的bean的a()方法的时候,被proxy$A
拦截后,执行proxy$A.a()
,没有执行async(),因此异步失效。