Github地址html
相關係列文章:java
本文講到的全部特性皆是基於Servlet 3.0 Async Processing的,不是基於Servlet 3.1 Async IO的。git
A
Callable<?>
can be returned when the application wants to produce the return value asynchronously in a thread managed by Spring MVC.
用於異步返回結果,使用的是Spring MVC的AsyncTaskExecutor
,Spring MVC使用CallableMethodReturnValueHandler
負責處理它。github
下面是例子CallableController:web
@RestController public class CallableController { @RequestMapping("callable-hello") public Callable<String> hello() { return () -> new SlowJob("CallableController").doWork(); } }
用瀏覽器訪問:http://localhost:8080/callable-hello 查看返回結果。spring
A
DeferredResult<?>
can be returned when the application wants to produce the return value from a thread of its own choosing.
用於異步返回結果,使用的是client code本身的thread,Spring MVC使用DeferredResultMethodReturnValueHandler
負責處理它。segmentfault
下面是例子DeferredResultController:瀏覽器
@RestController public class DeferredResultController { @Autowired @Qualifier("customExecutorService") private ExecutorService executorService; @RequestMapping("deferred-result-hello") public DeferredResult<String> hello() { DeferredResult<String> deferredResult = new DeferredResult<>(); executorService.submit(() -> { try { deferredResult.setResult(new SlowJob("DeferredResultController").doWork()); } catch (Exception e) { deferredResult.setErrorResult(e); } }); return deferredResult; } }
在這個例子裏使用了ExecutorService(見ExecutorServiceConfiguration),你也能夠根據實際狀況採用別的機制來給DeferredResult.setResult
。spring-mvc
用瀏覽器訪問:http://localhost:8080/deferred-result-hello 查看返回結果。mvc
AListenableFuture<?>
orCompletableFuture<?>
/CompletionStage<?>
can be returned when the application wants to produce the value from a thread pool submission.
用於異步返回結果,使用client code本身的thread pool,Spring MVC使用DeferredResultMethodReturnValueHandler
負責處理它。
下面是例子ListenableFutureController:
@RestController public class ListenableFutureController { @Autowired @Qualifier("customExecutorService") private ExecutorService executorService; @RequestMapping("listenable-future-hello") public ListenableFutureTask<String> hello() { ListenableFutureTask<String> listenableFutureTask = new ListenableFutureTask<>( () -> new SlowJob("ListenableFutureController").doWork()); executorService.submit(listenableFutureTask); return listenableFutureTask; } }
用瀏覽器訪問:http://localhost:8080/listenable-future-hello 查看返回結果。
下面是例子CompletionFutureController
@RestController public class CompletionFutureController { @RequestMapping("completable-future-hello") public CompletableFuture<String> hello() { return CompletableFuture .supplyAsync(() -> new SlowJob("CompletionFutureController").doWork()); } }
用瀏覽器訪問:http://localhost:8080/completable-future-hello 查看返回結果。
A
ResponseBodyEmitter can be returned to write multiple objects to the response asynchronously; also supported as the body within a
ResponseEntity
.
用於異步的寫入多個消息,使用的是client code本身的thread,Spring MVC使用ResponseBodyEmitterReturnValueHandler
負責處理它。
下面是例子ResponseBodyEmitterController
@RestController public class ResponseBodyEmitterController { @Autowired @Qualifier("customExecutorService") private ExecutorService executorService; @RequestMapping("response-body-emitter-hello") public ResponseBodyEmitter hello() { ResponseBodyEmitter emitter = new ResponseBodyEmitter(); executorService.submit(() -> { try { for (int i = 0; i < 5; i++) { String hello = new SlowJob("ResponseBodyEmitterController").doWork(); emitter.send("Count: " + (i + 1)); emitter.send("\n"); emitter.send(hello); emitter.send("\n\n"); } emitter.complete(); } catch (Exception e) { emitter.completeWithError(e); } }); return emitter; } }
用瀏覽器訪問:http://localhost:8080/response-body-emitter-hello 查看返回結果。
An
SseEmitter can be returned to write Server-Sent Events to the response asynchronously; also supported as the body within a
ResponseEntity
.
做用和ResponseBodyEmitter
相似,也是異步的寫入多個消息,使用的是client code本身的thread,區別在於它使用的是Server-Sent Events。Spring MVC使用ResponseBodyEmitterReturnValueHandler
負責處理它。
下面是例子SseEmitterController
@RestController public class SseEmitterController { @Autowired @Qualifier("customExecutorService") private ExecutorService executorService; @RequestMapping("sse-emitter-hello") public ResponseBodyEmitter hello() { SseEmitter emitter = new SseEmitter(); executorService.submit(() -> { try { for (int i = 0; i < 5; i++) { String hello = new SlowJob("SseEmitterController").doWork(); StringBuilder sb = new StringBuilder(); sb.append("Count: " + (i + 1)).append(". ").append(hello.replace("\n", "")); emitter.send(sb.toString()); } emitter.complete(); } catch (Exception e) { emitter.completeWithError(e); } }); return emitter; } }
用瀏覽器訪問:http://localhost:8080/sse-emitter-hello 查看返回結果。
A
StreamingResponseBody can be returned to write to the response OutputStream asynchronously; also supported as the body within a
ResponseEntity
.
用於異步write outputStream,使用的是Spring MVC的AsyncTaskExecutor
,Spring MVC使用StreamingResponseBodyReturnValueHandler
負責處理它。要注意,Spring MVC並無使用Servlet 3.1 Async IO([Read|Write]Listener)。
下面是例子StreamingResponseBodyController
@RestController public class StreamingResponseBodyController { @RequestMapping("streaming-response-body-hello") public StreamingResponseBody hello() { return outputStream -> { String hello = new SlowJob("CallableController").doWork(); outputStream.write(hello.getBytes()); outputStream.flush(); }; } }
用瀏覽器訪問:http://localhost:8080/streaming-response-body-hello 查看返回結果。
Spring MVC執行異步操做須要用到AsyncTaskExecutor
,這個能夠在用WebMvcConfigurer.configureAsyncSupport
方法來提供(相關文檔)。
若是不提供,則使用SimpleAsyncTaskExecutor
,SimpleAsyncTaskExecutor
不使用thread pool,所以推薦提供自定義的AsyncTaskExecutor
。
須要注意的是@EnableAsync
也須要用到AsyncTaskExecutor
,不過Spring MVC和它用的不是同一個。
順帶一提,EnableAsync
默認也使用SimpleAsyncTaskExecutor
,能夠使用AsyncConfigurer.getAsyncExecutor
方法來提供一個自定義的AsyncTaskExecutor
。
例子見:MvcAsyncTaskExecutorConfigurer。
AsyncHandlerInterceptor
,使用WebMvcConfigurer.addInterceptors
註冊CallableProcessingInterceptor[Adapter]
,使用WebMvcConfigurer.configureAsyncSupport
註冊DeferredResultProcessingInterceptor[Adapter]
,使用WebMvcConfigurer.configureAsyncSupport
註冊官方文檔:Intercepting Async Requests
WebAsyncManager
是Spring MVC管理async processing的中心類,若是你能夠閱讀它的源碼來更多瞭解Spring MVC對於async processing的底層機制。