资讯专栏INFORMATION COLUMN

Spring - Asynchronous Request

everfight / 3014人阅读

摘要:注意这时中结果为,即将原来的替换成,所以直接返回线程池执行的结果。提醒中的是你业务代码执行的步骤。所以异步异常处理和同步相同,在这段请求中处理。比多,调用时间即发起之前。正是请求被异步化,从而使得能,即。

用法
@GetMapping("/ffffd")
public Callable process() { 

    return () -> {
        Thread.sleep(1000L);
        return "call";
    };
}


@GetMapping("/ffffd")
public DeferredResult quotes() {
    DeferredResult deferredResult = new DeferredResult();
     
    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.

运行时

客户端请求,DispatcherType:REQUEST 即与同步请求一样

Controller返回Callable

HandlerMethodReturnValueHandlerComposite选出CallableMethodReturnValueHandler来处理Callable

WebAsyncManager#startCallableProcessing -> #startAsyncProcessing -> StandardServletAsyncWebRequest#startAsync

由于spring的StandardServletAsyncWebRequest内部托管J2EE容器的Request(该Request实现ServletRequest),所以调用ServletRequest#startAsync(ServletRequest, ServletResponse)生成AsyncContext托管于StandardServletAsyncWebRequest内部,该AsyncContext保存ServletRequest和ServletResponse,以便之后的DispatcherType:ASYNC请求能取出对应的ServletResponse

WebAsyncManager#startCallableProcessing 调用完毕后,向taskExecutor线程池中提交任务来执行Callable#call,注意该任务最后必定会执行WebAsyncManager#setConcurrentResultAndDispatch,即执行StandardServletAsyncWebRequest#dispatch,就是执行前面生成的AsyncContext#dispatch

DispatcherType:ASYNC 这是由AsyncContext#dispatch发起的。

注意这时RequestMappingHandlerAdapter#invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)中if (asyncManager.hasConcurrentResult())结果为true,即将原来的ServletInvocableHandlerMethod替换成ConcurrentResultHandlerMethod,所以invocableMethod.invokeAndHandle(webRequest, mavContainer);直接返回taskExecutor线程池执行的结果。

HandlerMethodReturnValueHandlerComposite选出你结果类型对应的ReturnValueHandler来处理你的结果。

返回客户端。

提醒:RequestMappingHandlerAdapter#invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)中的invocableMethod.invokeAndHandle(webRequest, mavContainer);是你业务代码执行的步骤。

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.

运行时流程有点绕,没功夫画时序图。

Exception Handling

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这段请求中处理。

Intercepting Async Requests

The DeferredResult type also provides methods such as onTimeout(Runnable) and onCompletion(Runnable).

When using a Callable you can wrap it with an instance of WebAsyncTask which also provides registration methods for timeout and completion.

AsyncHandlerInterceptor比HandlerInterceptor多#afterConcurrentHandlingStarted,调用时间即DispatcherType:ASYNC发起之前。

HTTP Streaming

正是请求被异步化,从而使得能long polling,即HTTP Streaming。

可以用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.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71000.html

相关文章

  • Java Reactive Web设计与实现

    摘要:概念响应式编程,异步非阻塞就是响应式编程,与之相对应的是命令式编程。的另外一种实现方式就是消息队列。非阻塞设计利用规范中的实现实现代码链接 注: 本文是由读者观看小马哥公开课视频过程中的笔记整理而成。更多Spring Framework文章可参看笔者个人github: spring-framework-lesson 。 0. 编程模型与并发模型 Spring 5实现了一部分Reacti...

    siberiawolf 评论0 收藏0
  • Spring MVC异步处理简介

    摘要:异步处理简介地址相关系列文章异步处理详解分析本文讲到的所有特性皆是基于的,不是基于的。用于异步返回结果,使用自己的,使用负责处理它。配置执行异步操作需要用到,这个可以在用方法来提供相关文档。 Spring MVC异步处理简介 Github地址 相关系列文章: Servlet 3.0 异步处理详解 Servlet 3.1 Async IO分析 本文讲到的所有特性皆是基于Servlet...

    Sike 评论0 收藏0
  • tornado6与python3.7 异步新姿势

    摘要:这是我重新复习的原因放弃了之前自己实现的全面拥抱的这个改动是非常大的而且阅读的源码可以发现其中大部分函数都支持了类型检验和返回值提示值得阅读 废话不多说,直接上代码 __auth__ = aleimu __doc__ = 学习tornado6.0+ 版本与python3.7+ import time import asyncio import tornado.gen import t...

    maxmin 评论0 收藏0
  • 从JDK11新增HttpClient谈谈非阻塞模型

    摘要:是一个倡议,它提倡提供一种带有非阻塞背压的异步流处理的标准。是标准的实现之一。的实现细节请求响应的与请求响应的暴露为是请求的的消费者是响应的的生产者内部的内部 北京时间 9 月 26 日,Oracle 官方宣布 Java 11 正式发布 一、JDK HTTP Client介绍 JDK11中的17个新特性 showImg(https://segmentfault.com/img/remo...

    pingan8787 评论0 收藏0
  • 《Java编程方法论:响应式RxJava与代码设计实战》序

    摘要:原文链接编程方法论响应式与代码设计实战序,来自于微信公众号次灵均阁正文内容在一月的架构和设计趋势报告中,响应式编程和函数式仍旧编列在第一季度的早期采纳者中。 原文链接:《Java编程方法论:响应式RxJava与代码设计实战》序,来自于微信公众号:次灵均阁 正文内容 在《2019 一月的InfoQ 架构和设计趋势报告》1中,响应式编程(Reactive Programming)和函数式...

    PAMPANG 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<