SpringBoot中使用@Async註解失效問題記錄
阿新 • • 發佈:2018-12-19
錯誤示例,同一個類中使用非同步方法:
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秒之後才會列印結果: