Spring中註解方式的異步請求
一、Servlet3.0異步請求
@WebServlet(value = "/async", asyncSupported = true) public class HelloAsyncServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1、設置支持異步處理asyncSupported = true //2、開啟異步模式 System.out.println("主線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); AsyncContext startAsync = req.startAsync(); //3、業務邏輯進行異步處理,開始異步處理 startAsync.start(new Runnable() { @Override public void run() { try { System.out.println("副線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); sayHello(); //獲取到異步的上下文 AsyncContext asyncContext = req.getAsyncContext(); startAsync.complete(); ServletResponse response = asyncContext.getResponse(); response.getWriter().write("hello async!"); System.out.println("副線程結束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println("主線程結束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); } public void sayHello() throws Exception { System.out.println(Thread.currentThread() + "processing..."); Thread.sleep(3000); } }
打印結果:
二、SpringMVC的異步請求
返回Callable
@Controller public class AsyncController { @ResponseBody @RequestMapping("/async01") public Callable<String> async01(){ System.out.println("主線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); Callable<String> callable = new Callable<String>() { public String call() throws Exception { System.out.println("副線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); Thread.sleep(2000); System.out.println("副線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); return "async01"; } }; System.out.println("主線程結束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); return callable; } }
- 控制器返回
Callable
- Spring進行異步處理,將
Callable
提交給TaskExecutor
,使用一個隔離的線程進行執行 DispatcherServlet
和所有的Filter
退出Web容器的線程,但是response
保持打開狀態Callable
返回結果,SpreingMVC將請求重新派發給容器,恢復之前的處理,Callable
返回值就是目標方法的返回值- 根據
Callable
返回的結果,SpringMVC繼續進行視圖渲染流程等(從收到請求到視圖渲染)
輸出結果:
返回DeferredResult
模擬一個消息中間件
public class DeferredResultQueue { private static Queue<DeferredResult<Object>> queue = new ConcurrentLinkedDeque<DeferredResult<Object>>(); public static void save(DeferredResult<Object> deferredResult){ queue.add(deferredResult); } public static DeferredResult<Object> get(){ return queue.poll(); } }
/createOrder
請求會暫時保存DeferredResultQueue
中,/create
請求會獲取DeferredResultQueue
中的請求,進行業務邏輯的處理並返回結果
@Controller public class AsyncController { @ResponseBody @RequestMapping("/createOrder") public DeferredResult<Object> createOrder(){ DeferredResult<Object> deferredResult = new DeferredResult<Object>((long)3000,"create fail"); DeferredResultQueue.save(deferredResult); return deferredResult; } @ResponseBody @RequestMapping("/create") public String create(){ String order = UUID.randomUUID().toString(); DeferredResult<Object> deferredResult = DeferredResultQueue.get(); deferredResult.setResult(order); return "success:" + order; } }
到此這篇關於Spring中註解方式的異步請求的文章就介紹到這瞭,更多相關註解方式的異步請求內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- springMvc中DeferredResult的long polling應用示例解析
- Spring中的使用@Async異步調用方法
- Java SpringMVC異步處理詳解
- Java創建線程及配合使用Lambda方式
- Java使用Runnable和Callable實現多線程的區別詳解