@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