Async--CompletableFuture作为返回值

  1. 以下是Servlet异步请求处理的简要概述:
  2. DeferredResult 处理工作如下:
  3. Callable 处理工作如下:
  • 异常处理
  • 截击
  • 与WebFlux相比
  • 以tomcat(支持Servlet 3.0的)为例,你controller方法指定返回DeferredResult或Callable,spring会自动进行异步处理,将方法以及响应的任务交给spring默认或者你定义的taskExecutor线程池bean执行,原本tomcat负责处理请求的线程返回tomcat线程池,不影响servlet接受请求的能力。要阻塞也是taskExecutor线程池里的线程,而不是tomcat线程池的线程。

    一旦 在Servlet容器中启用了异步请求处理功能,控制器方法就可以包装任何支持的控制器方法返回值DeferredResult

    控制器可以使用包装任何支持的返回值java.util.concurrent.Callable

    以下是Servlet异步请求处理的简要概述:

    • 一个ServletRequest可以通过调用置于异步模式request.startAsync()。这样做的主要作用是Servlet(以及任何过滤器)可以退出,但响应保持打开状态以便稍后处理完成。

    • 对request.startAsync()返回的调用AsyncContext,可用于进一步控制异步处理。例如,它提供的dispatch方法类似于Servlet API的转发,但它允许应用程序在Servlet容器线程上恢复请求处理。

    • 在ServletRequest提供对电流DispatcherType,它可以使用处理该初始请求,异步调度,正向,以及其他的调度类型之间进行区分。

    DeferredResult 处理工作如下:

    控制器返回a DeferredResult并将其保存在可以访问它的某个内存中队列或列表中。

    Spring MVC调用request.startAsync()。

    同时,DispatcherServlet所有已配置的过滤器都会退出请求处理线程,但响应仍保持打开状态。

    应用程序DeferredResult从某个线程设置,Spring MVC将请求调度回Servlet容器。

    将DispatcherServlet被再次调用,并且处理与异步生产返回值恢复。

    Callable 处理工作如下:

    控制器返回一个Callable。

    Spring MVC调用request.startAsync()并将其提交Callable到a TaskExecutor以在单独的线程中进行处理。

    同时,DispatcherServlet所有过滤器都退出Servlet容器线程,但响应仍保持打开状态。

    最终Callable产生一个结果,Spring MVC将请求发送回Servlet容器以完成处理。

    将DispatcherServlet被再次调用,并且处理从所述异步生产返回值恢复Callable。

    有关更多背景和上下文,您还可以阅读 在Spring MVC 3.2中引入异步请求处理支持的博客文章。

    异常处理

    使用a时DeferredResult,您可以选择是调用setResult还是 setErrorResult使用异常。在这两种情况下,Spring MVC都会将请求发送回Servlet容器以完成处理。然后对其进行处理,就像控制器方法返回给定值一样,或者好像它产生了给定的异常。然后异常通过常规异常处理机制(例如,调用 @ExceptionHandler方法)。

    当你使用时Callable,会出现类似的处理逻辑,主要区别在于结果是从它返回的Callable或异常引发的。

    截击

    HandlerInterceptor实例可以是类型AsyncHandlerInterceptor,以接收afterConcurrentHandlingStarted启动异步处理(而不是postHandle和afterCompletion)的初始请求的 回调。

    HandlerInterceptor实现还可以注册a CallableProcessingInterceptor 或a DeferredResultProcessingInterceptor,以更深入地集成异步请求的生命周期(例如,处理超时事件)。有关AsyncHandlerInterceptor 详细信息,请参阅

    DeferredResult提供onTimeout(Runnable)和onCompletion(Runnable)回调。有关 更多详细信息,请参阅javadocDeferredResult。Callable可以替换为WebAsyncTask暴露额外的超时和完成回调方法。

    与WebFlux相比

    Servlet API最初是为了通过Filter-Servlet链进行单次传递而构建的。Servlet 3.0中添加的异步请求处理允许应用程序退出Filter-Servlet链,但保持响应打开以进行进一步处理。Spring MVC异步支持是围绕该机制构建的。当控制器返回a时DeferredResult,退出Filter-Servlet链,并释放Servlet容器线程。稍后,当DeferredResult设置时,进行ASYNC调度(到相同的URL),在此期间再次映射控制器,但DeferredResult不使用它,而是使用该值(就像控制器返回它一样)以恢复处理。

    相比之下,Spring WebFlux既不是基于Servlet API构建的,也不需要这样的异步请求处理功能,因为它在设计上是异步的。异步处理内置于所有框架合同中,并通过请求处理的所有阶段进行内在支持。

    从编程模型的角度来看,Spring MVC和Spring WebFlux都支持异步和反应类型作为控制器方法中的返回值。Spring MVC甚至支持流媒体,包括反应性背压。但是,对响应的单独写入仍然是阻塞的(并且在单独的线程上执行),这与WebFlux不同,后者依赖于非阻塞I / O,并且每次写入都不需要额外的线程。

    另一个根本区别在于Spring MVC的不支持在控制器方法参数异步或反应性类型(例如,@RequestBody,@RequestPart,及其他),也不象模型属性它有用于异步和反应性类型的任何显式支持。Spring WebFlux确实支持所有这些。


    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wshten@gmail.com

    文章标题:Async--CompletableFuture作为返回值

    本文作者:KevinTen

    发布时间:2019-09-03, 00:00:00

    最后更新:2019-09-04, 16:40:05

    原始链接:http://github.com/kevinten10/2019/09/03/Async/Future/Async-Future-异步返回值/

    版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

    目录
    ×

    喜欢就点赞,疼爱就打赏

    csdn zhihu github