上節(jié)課我們學(xué)了這樣的一個(gè)結(jié)構(gòu)(這個(gè)結(jié)構(gòu)也是在我們實(shí)際開發(fā)時(shí)經(jīng)常使用的異步請(qǐng)求方式袍暴,當(dāng)我們有些業(yè)務(wù)比較耗時(shí)的時(shí)候倒源,我們應(yīng)該異步處理)
這節(jié)課我們首先模擬下超時(shí)的過程(需要對(duì)上節(jié)課異步代碼做下簡(jiǎn)單的修改)
上節(jié)課我們修改了tomcat最大線程數(shù)(改成了很小)
在我們進(jìn)行異步提交的同時(shí)孵稽,依然可以進(jìn)行同步提交 因?yàn)楫?dāng)前的線程已經(jīng)釋放掉了(tomcat可以繼續(xù)接納客人(請(qǐng)求)繼續(xù)進(jìn)行相應(yīng) 只不過一些耗時(shí)的處理需要放在Callable里面)
比如上節(jié)課我們模擬的延時(shí)3s
這個(gè)接口對(duì)應(yīng)我們異步按鈕(test1.html)
當(dāng)我們點(diǎn)擊異步(async)按鈕時(shí) 延時(shí)3s后彈出結(jié)果
這里面的細(xì)節(jié)我們看下文檔
我們?cè)诠倬W(wǎng)手冊(cè)里搜索SimpleAsyncTaskExecutor
可以定位到說明如下
Spring MVC默認(rèn)使用SimpleAsyncTaskExecutor類來處理多線程(高并發(fā))可以定義攔截器進(jìn)行處理攔截
SimpleAsyncTaskExecutor在并發(fā)并不是很高的情況下(服務(wù)器壓力不是很大情況下)可以直接使用
SimpleAsyncTaskExecutor并不是Spring MVC里面的內(nèi)容 它在Spring主目錄里的Integration下
來到文檔https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#spring-integration
搜索SimpleAsyncTaskExecutor(異步任務(wù)執(zhí)行器)
可以看見如下
它分為幾種類型 簡(jiǎn)單列舉如下
一般我們不用SimpleAsyncTaskExecutor而使用ThreadPoolTaskExecutor (是一個(gè)比較常用的線程池執(zhí)行器,一般使用它設(shè)置一些線程的大小接校,設(shè)置緩沖 等待隊(duì)列 空閑線程 存活時(shí)間等)
那么我們這節(jié)課介紹下另外一種方式WebAsyncTask
實(shí)際上我們?cè)谧霎惒秸?qǐng)求的時(shí)候蛛勉,經(jīng)常會(huì)碰到超時(shí)的過程 也就是如下圖 瀏覽器發(fā)起請(qǐng)求 tomcat線程處理不發(fā)生阻塞 因?yàn)榘讶蝿?wù)交給另外一個(gè)單獨(dú)線程處理 那么這時(shí)候這個(gè)單獨(dú)線程在這里出現(xiàn)了問題(比如說超時(shí)了)那么是否讓我們前端不斷的去等待毡熏,這時(shí)其實(shí)我們應(yīng)該對(duì)超時(shí)做出處理 因此官方提供了WebAsyncTask
下面代碼演示下對(duì)超時(shí)做出處理 (WebAsyncTask)
為了演示前臺(tái)請(qǐng)求超時(shí)處理
我們修改下代碼
在NewsController中(上節(jié)課代碼)
前臺(tái)代碼test1.html
做異步請(qǐng)求時(shí) 加入?yún)?shù)t 控制延時(shí)多少秒
下面我們修改下NewsController中addUser 使其返回WebAsyncTask(處理超時(shí))
修改完代碼 我們編譯運(yùn)行下代碼
編譯完成來到前端頁面
我們測(cè)試下
點(diǎn)擊async_submit按鈕
可以發(fā)現(xiàn)很準(zhǔn)確的3s彈出對(duì)話框
然后我們點(diǎn)擊async_submit(timeout)按鈕
由于我們?cè)谇芭_(tái)設(shè)置4s才能完成請(qǐng)求
我們點(diǎn)擊按鈕
結(jié)果如下
必定會(huì)返回超時(shí)的內(nèi)容(因?yàn)槲覀兒笈_(tái)設(shè)置了超時(shí)的處理)
接下來我們學(xué)下異常(exceptionHandler)文檔中搜索https://docs.spring.io/spring/docs/5.0.1.BUILD-SNAPSHOT//spring-framework-reference/web.html#mvc-ann-rest-exceptions
異常處理只需要在方法前面加上@exceptionHandler注即可
在異步請(qǐng)求里的異常的處理方式和處理普通異常是一樣的
下面代碼演示下
比如我們超時(shí)后直接throw 一個(gè)新的異常
重新發(fā)布代碼
再次運(yùn)行l(wèi)ocalhost:8080/test1/html
點(diǎn)擊 async_submit(timeout)按鈕
表示請(qǐng)求處理超時(shí)了
我們?cè)谔幚懋惓5臅r(shí)候 可以把異常進(jìn)行定義 如果攔截到超時(shí)異常 我們專門做一些返回值的處理或者日志的記錄