SpringBoot @Async 異步注解無效


解決思路:

  1. 先查看啟動類是否加上 @EnableAsync 注解,如果沒有,就加上該注解再重新啟動
  2. 查看異步方法的調用方式是否正確

@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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM