解决思路:
@Async的调用涉及到动态代理,如果直接将需要异步操作的方法写到业务类中,业务类直接调用,则执行逻辑不会走到代理类,异步就会失效
例如用下面的方式调用(错误演示),异步就不会生效,打印的结果必定为:1 2 3
@SpringBootApplication
@EnableAsync
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@Service
class AAAService{
public void AAAMethod(){
System.out.println("1");
asyncMethod();
System.out.println("3");
}
@Async
public void asyncMethod(){
System.out.println("2");
}
}
因此需要将 @Async 注解的方法单独拿出来封装到一个类中,再将这个类注入到业务类中,业务类通过这个类来调用异步方法
@SpringBootApplication
@EnableAsync
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@Service
class AAAService{
@Autowire
private AsyncManage asyncManage;
public void AAAMethod(){
System.out.println("1");
asyncManage.asyncMethod();
System.out.println("3");
}
}
@Component
class AsyncManage{
@Async
public void asyncMethod(){
System.out.println("2");
}
}
输出结果为:1 3 2 (如果异步线程执行的很快,也有很小的概率是1 2 3)
(代码存手打,不知道有没有啥问题,能看懂意思就行...)
另外在网上也看到一些失效原因分析,贴过来看一下:
1.异步方法使用注解@Async的返回值只能为void或者Future。
2.没有走Spring的代理类。因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器。
https://blog.csdn.net/YoungLee16/article/details/88398045
原文:https://www.cnblogs.com/codeclock/p/12625474.html