jetty中springMVC的contoller返回DeferredResult的理解

1.servlet会请求两次

一个是public void handle(HttpChannel channel);

另一个是public void handleAsync(HttpChannel channel)

第一次是在httpConnection中通过onFillable()方法调用HttpChannel的handle()方法(正常请求都是通过此执行的)

第二次在httpchannelState中的dispatch方法(添加httpChannel任务到线程池中,会再次调用handle()方法)执行的

2.正常流程

(1)第一次servlet调用deferredResultMethodReturnValueHandler的handleReturnValue()方法时,先设置standardServletAsyncWebRequest的startAsync()方法(其中执行asyncContext.addListener(this),添加处理成功,处理失败,处理超时的逻辑),同时设置deferredResult的deferredResultHandler的处理器。

(2)异步 deferredResult执行完setResult方法后通过调用deferredResultHandler才执行standardServletAsyncWebRequest中的dispatch,最终执行httpChannelState中的dispatch方法,才会再次发起servlet请求

3.超时设置的原理

httpChannelState中unhandle()方法在async状态设为started(第一次startAsync()方法)后,会执行scheduler.schedule(_event,_timeoutMs,TimeUnit.MILLISECONDS),延时添加到调度线程池中,如果这个run方法执行了,则代表超时了,正常执行后这个task要取消掉。

4.两次servlet的请求的区别

1.第一次请求与第二次请求是同一个reqeust,共用一个webAsyncManager,第一次请求时设置了concurrentResutl的值,第二次时取到了这个结果, 不会再进入controller方法。

2.第一次请求调用原始方法能过反射的方式,执行得到结果,第二次请求是重新包装了一个新的类concurrentResultHandlerMethod,原样得到结果

3.第一次handlerMethodReturnValueHandler是deferredResultMethodReturnValueHandler

 第二次handlerMethodReturnValueHandler根据deferredResult<T>中T类型匹配

注:由于涉及多线程,所以DeferredResult中要用到volatile

5.正常执行与超时执行

正常执行与超时执行都会调用两次servlet,区别是:

(1)正常执行的在异步线程中设置DeferredResult中的result是正常的值

  (2) 超时执行在schedule中设置DeferredResult中的result是AsyncRequestTimeoutException

这样在第二次servlet会不同,正常执行的第二次servlet是原样返回异步线程中设置的值,超时执行则抛出异常(ConcurrentResultHandlerMethod)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值