Spring自身提供的一个类DeferredResult(用于作为异步请求的替代方案)

2023-04-11 07:57:55

Spring官方的Spring框架文档中,针对异步请求:提供了两个类来实现:
DeferredResult 和 Callable

Spring中的DeferredResult
设计思想
提供了使用可调用异步请求处理的替代方案,可以给一个线程A的结果设置为DeferredResult。
之后,在另一个线程B对A线程的该结果进行赋值。
主要属性
结果超时时间 timeout
超时默认结果 timeoutResult
超时执行函数 timeoutCallback
完成执行函数 completionCallback

设置结果方法
DeferredResult.setResult()方法

项目使用DeferredResult的具体场景
场景描述:
收费员端根据信息,发起收费(在一个平板上显示二维码),患者通过手机进行支付。
由于,接口被请求后(收费员端携带收费信息),患者需要时间进行支付,所以接口请求后,需要等待一段时间,才有最终结果。
此时,对于接口调用方来说:是同步的,因为一个调用,一个结果。
但是对于被调用方,是异步的,因为,该线程收到支付请求后,并不知道是否支付成功。需要另外的线程进行通知。
一句话描述:结果在一个线程中不能马上得到,需要时间进行处理,之后另一个线程进行统通知。

DeferredResult和Servlet的关系

DeferredResult原理
Spring框架帮我们做了很多事情。
DeferredResult这个实现,和web请求是强相关的,只有web请求时,才会用到该类。

DeferredResult and Callable return values in controller methods and
provide basic support for a single asynchronous return value.-官方文档

DeferredResult的处理流程如下(来自官方文档):
1、控制器返回DeferredResult,(我们使用者)并将它保存在可以访问的内存队列或者列表中;
2、Spring调用request.startAsync();(我的理解,调用该方法后,该Servlet 线程结束,故Tomcat的Servlet线程池中的线程得到释放,可以进行其他的请求处理)
3、DispatcherServlet和过滤器退出处理线程,但响应保持打开
4、DeferredResult从某个线程被设置,Spring MVC将请求分派回Servlet容器;
5、DispatcherServlet被调用,处理和返回最终值

备注:
Spring的DispatcherServlet这个模块设计到Servlet结果的赋值,如果要想完全了解DeferredResult背后Spring的工作机制,那么需要研究下。
如下:

    @ApiOperation(value = "接口一")
	@GetMapping("/order")
	public DeferredResult<OrderInfo> createOrder(String outTradeNo) {
		DeferredResult<OrderInfo> result = new DeferredResult<>();
		OrderDeferredResultSupporter.registDeferredResult(outTradeNo, result);
		return result;
	}
  • 作者:peacejl
  • 原文链接:https://blog.csdn.net/Fishandbearspaw/article/details/108925096
    更新时间:2023-04-11 07:57:55