一、背景
在日常的開發過程中,我們往往會遇到以下一些場景:當我們調用第三方接口或者方法的時候,我們不需要等待方法返回才去執行其它邏輯,這時如果響應時間過長,就會極大的影響程序的執行效率。所以這時就需要使用異步方法來並行執行我們的邏輯。同樣,在執行IO操作等耗時操作時,因為比較影響客戶體驗和使用性能,通常情況下我們也可以使用異步方法。類似的應用還有比如發送短信、發送郵件或者消息通知等這些時效性不高的操作都可以適當的使用異步方法。
不過異步操作增加了代碼的復雜性,所以我們應該謹慎使用,稍有不慎就可能產生意料之外的結果,從而影響程序的整個邏輯。
二、測試
下面我們使用一個簡單的例子來看一下如何在springboot使用@Async注解實現異步操作
首先在啟動類上添加 @EnableAsync 注解
TestController.java
@RestController @Slf4j public class TestController { @Autowired AsyncDemo asyncDemo; @GetMapping("/testAsync01") public void testAsync01() { asyncDemo.async01(); asyncDemo.async02(); try { log.info("start other task..."); Thread.sleep(1000); log.info("other task end..."); } catch (InterruptedException e) { e.printStackTrace(); } } }
AsyncDemo.java
/** * <p> * 測試異步方法 * </p> * * @className AsyncDemo * @author Sue * @create 2020/12/30 **/ @Slf4j @Component public class AsyncDemo { @Async public void async01() { log.info("thread{} start at{}", Thread.currentThread().getName(), System.currentTimeMillis()); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("thread{} end at{}", Thread.currentThread().getName(), System.currentTimeMillis()); } @Async public void async02() { log.info("thread{} start at{}", Thread.currentThread().getName(), System.currentTimeMillis()); System.out.println(1/0); log.info("thread{} end at{}", Thread.currentThread().getName(), System.currentTimeMillis()); } }
測試,控制台輸出

通過日志可以看出,方法async01和async02並沒有影響后面的代碼段執行,即使是方法拋出異常也不會影響其他代碼的運行。說明此時,我們成功調用了異步方法。
三、補充
在使用springboot框架執行異步方法時,有以下幾點需要注意
- 必須在啟動類中增加@EnableAsync注解;
- 異步類沒有被springboot管理,添加@Component注解(或其他注解)且保證可以掃描到異步類;
- 測試異步方法不能與異步方法在同一個類中;
- 測試類中需要使用spring容器初始化的異步類,不能自己手動new對象;
異步方法如果有返回值時,可以使用如下寫法:


四、總結
這篇文章簡單介紹了一下如何在springboot中使用 @Async 注解調用異步方法以及注意點,關於 @Async 注解的更多使用可以看我的另一篇文章 springboot使用@Async注解時異步方法不生效原因分析及解決方案 。
