您好,登錄后才能下訂單哦!
小編給大家分享一下Spring中注解方式的異步請(qǐng)求如何實(shí)現(xiàn),希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
@WebServlet(value = "/async", asyncSupported = true) public class HelloAsyncServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1、設(shè)置支持異步處理asyncSupported = true //2、開啟異步模式 System.out.println("主線程開始:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); AsyncContext startAsync = req.startAsync(); //3、業(yè)務(wù)邏輯進(jìn)行異步處理,開始異步處理 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("副線程結(jié)束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println("主線程結(jié)束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); } public void sayHello() throws Exception { System.out.println(Thread.currentThread() + "processing..."); Thread.sleep(3000); } }
打印結(jié)果:
返回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("主線程結(jié)束:" + Thread.currentThread() + "==>" + System.currentTimeMillis()); return callable; } }
控制器返回Callable
Spring進(jìn)行異步處理,將Callable
提交給TaskExecutor
,使用一個(gè)隔離的線程進(jìn)行執(zhí)行
DispatcherServlet
和所有的Filter
退出Web容器的線程,但是response
保持打開狀態(tài)
Callable
返回結(jié)果,SpreingMVC將請(qǐng)求重新派發(fā)給容器,恢復(fù)之前的處理,Callable
返回值就是目標(biāo)方法的返回值
根據(jù)Callable
返回的結(jié)果,SpringMVC繼續(xù)進(jìn)行視圖渲染流程等(從收到請(qǐng)求到視圖渲染)
輸出結(jié)果:
返回DeferredResult
模擬一個(gè)消息中間件
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
請(qǐng)求會(huì)暫時(shí)保存DeferredResultQueue
中,/create
請(qǐng)求會(huì)獲取DeferredResultQueue
中的請(qǐng)求,進(jìn)行業(yè)務(wù)邏輯的處理并返回結(jié)果
@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; } }
看完了這篇文章,相信你對(duì)“Spring中注解方式的異步請(qǐng)求如何實(shí)現(xiàn)”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。