1. 程式人生 > 實用技巧 >springboot使用@Async註解實現方法的非同步呼叫

springboot使用@Async註解實現方法的非同步呼叫

一、背景

  在日常的開發過程中,我們往往會遇到以下一些場景:當我們呼叫第三方介面或者方法的時候,我們不需要等待方法返回才去執行其它邏輯,這時如果響應時間過長,就會極大的影響程式的執行效率。所以這時就需要使用非同步方法來並行執行我們的邏輯。同樣,在執行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框架執行非同步方法時,有以下幾點需要注意

  1. 必須在啟動類中增加@EnableAsync註解;
  2. 非同步類沒有被springboot管理,新增@Component註解(或其他註解)且保證可以掃描到非同步類;
  3. 測試非同步方法不能與非同步方法在同一個類中;
  4. 測試類中需要使用spring容器初始化的非同步類,不能自己手動new物件;

非同步方法如果有返回值時,可以使用如下寫法:

四、總結

這篇文章簡單介紹了一下如何在springboot中使用@Async註解呼叫非同步方法以及注意點,關於@Async註解的更多使用可以看我的另一篇文章 。