解決思路:
- 先查看啟動類是否加上 @EnableAsync 注解,如果沒有,就加上該注解再重新啟動
- 查看異步方法的調用方式是否正確
@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