@GetMapping("/ddd") public Callable<String> process() { return () -> { Thread.sleep(1000L); return "call"; }; } @GetMapping("/ddd") public DeferredResult<String> quotes() { DeferredResult<String> deferredResult = new DeferredResult<String>(); return deferredResult; } // In some other thread... deferredResult.setResult(data);
返回Callable和DeferredResult區別在於the return value of DeferredResult will also be produced from any thread, i.e. one that is not managed by Spring MVC.web
提醒:RequestMappingHandlerAdapter#invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)中的invocableMethod.invokeAndHandle(webRequest, mavContainer);是你業務代碼執行的步驟。spring
The call to request.startAsync() returns AsyncContext which can be used for further control over async processing. For example it provides the method dispatch, that is similar to a forward from the Servlet API except it allows an application to resume request processing on a Servlet container thread.app
運行時流程有點繞,沒功夫畫時序圖。異步
when a Callable raises an Exception Spring MVC dispatches to the Servlet container with the Exception as the result and that leads to resume request processing with the Exception instead of a controller method return value. When using a DeferredResult you have a choice whether to call setResult or setErrorResult with an Exception instance.
因此異步異常處理和同步相同,在DispatcherType:ASYNC這段請求中處理。async
AsyncHandlerInterceptor比HandlerInterceptor多#afterConcurrentHandlingStarted,調用時間即DispatcherType:ASYNC發起以前。ide
正是請求被異步化,從而使得能long polling,即HTTP Streaming。spa
能夠用ResponseBodyEmitter來建立邏輯上的Streaming,注意ResponseBodyEmitter#send的內容都會經過對應的HttpMessageConverter來轉化:線程
@RequestMapping("/events") public ResponseBodyEmitter handle() { ResponseBodyEmitter emitter = new ResponseBodyEmitter(); // Save the emitter somewhere.. return emitter; } // In some other thread emitter.send("Hello once"); // and again later on emitter.send("Hello again"); // and done at some point emitter.complete();
固然 ResponseBodyEmitter can also be used as the body in a ResponseEntity in order to customize the status and headers of the response.code