SpringMVC與Servlet3.0整合 - 非同步處理

來源:互聯網
上載者:User

Servlet3.0提供了非同步處理支援,SpringMVC對其進行了封裝,可以通過兩種方式進行非同步處理。 【1】Callable

官方文檔地址:

https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/web.html#mvc-ann-async-callable

其原理如下:

1、控制器返回Callable
2、Spring非同步處理,將Callable 提交到 TaskExecutor 使用一個隔離的線程進行執行
3、DispatcherServlet和所有的Filter退出web容器的線程,但是response 保持開啟狀態;
4、Callable返回結果,SpringMVC將請求重新派發給容器,恢複之前的處理;
5、根據Callable返回的結果。SpringMVC繼續進行視圖渲染流程等(從收請求-視圖渲染)。

程式碼範例如下:

    @ResponseBody    @RequestMapping("/async01")    public Callable<String> async01(){        System.out.println("主線程開始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());        Callable<String> callable = new Callable<String>() {            @Override            public String call() throws Exception {                System.out.println("副線程開始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());                Thread.sleep(2000);                System.out.println("副線程開始..."+Thread.currentThread()+"==>"+System.currentTimeMillis());                return "Callable<String> async01()";            }        };        System.out.println("主線程結束..."+Thread.currentThread()+"==>"+System.currentTimeMillis());        return callable;    }

測試如下:

【2】DeferredResult

一旦啟用了非同步請求處理功能 ,控制器就可以將傳回值封裝在DeferredResult,控制器可以從不同的線程非同步產生傳回值。

優點就是可以實現兩個完全不相干的線程間的通訊。

首先建立一個儲存DeferredResult的執行個體

public class DeferredResultQueue {    private static Queue<DeferredResult<Object>> queue = new ConcurrentLinkedQueue<DeferredResult<Object>>();    public static void save(DeferredResult<Object> deferredResult){        queue.add(deferredResult);    }    public static DeferredResult<Object> get( ){        return queue.poll();    }}

兩個要求方法如下:

    @ResponseBody    @RequestMapping("/createOrder")    public DeferredResult<Object> createOrder(){        DeferredResult<Object> deferredResult = new DeferredResult<>((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;    }

首先http://localhost:8080/springmvc-annotation/createOrder請求擷取order,有結果返回,超出等待時間返回建立失敗。

http://localhost:8080/springmvc-annotation/create請求建立order,並給deferredResult賦值。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.