1. 程式人生 > >SpringBoot中使用@Async註解失效問題記錄

SpringBoot中使用@Async註解失效問題記錄

錯誤示例,同一個類中使用非同步方法:

package com.xqnode.learning.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @RestController @RequestMapping("/test") public class TestController { @GetMapping("/async") public Map<Object, Object> test() throws InterruptedException, JsonProcessingException { System.out.println("接收到請求。。。"
); task(); Map<Object, Object> map = new HashMap<>(); System.out.println("請求結束。。。"); map.put("msg", "操作成功"); map.put("code", "0"); return map; } @Async void task() throws InterruptedException { TimeUnit.SECONDS.sleep(5); System.out.println("執行緒任務執行結束。。。"
); } }

來分析下錯誤的原因:
當我使用postman呼叫該介面的時候發現,我預想中的立即返回並沒有發生。後來查詢資料發現,我在同一個controller中呼叫,在介面方法中呼叫了非同步方法。這是不會生效的。

正確示例:

package com.xqnode.learning.controller;

import com.xqnode.learning.service.AsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/test")
public class TestController {

    private static final Logger LOG = LoggerFactory.getLogger(TestController.class);

    @Autowired
    private AsyncService asyncService;

    @GetMapping("/async")
    public Map<Object, Object> test() throws InterruptedException {
        LOG.info("接收到請求。。。");
        asyncService.task();
        Map<Object, Object> map = new HashMap<>();
        LOG.info("請求結束。。。");
        map.put("msg", "操作成功");
        map.put("code", "0");
        return map;
    }
}

將非同步呼叫放到service中:

package com.xqnode.learning.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class AsyncService {

    private static final Logger LOG = LoggerFactory.getLogger(AsyncService.class);


    @Async("asyncExecutor")
    public void task() throws InterruptedException {

        TimeUnit.SECONDS.sleep(5);
        LOG.info("執行緒任務執行結束。。。");
    }
}

這時候再重啟專案請求該介面,就會發現介面可以立即返回值。而task任務是非同步執行的,5秒之後才會列印結果:
這裡寫圖片描述