Spring Boot使用Spring DeferredResult实现长轮询,纵享新丝滑让你体验丝滑般的感觉 - 第414篇

导读

         Spring 3.2开始引入了DeferredResult,有助于将长时间运行的计算从http-worker线程卸载到单独的线程。

         这一节我们将来一探Spring DeferredResult,看看它究竟是何方神圣。

         长轮询系列:

(1)✅《什么是轮询、长轮询、长连接一篇文章让你不在懵懂》

(2)✅《Spring Boot使用Servlet居然也可以实现长轮询》

(3)✅《Spring Boot使用Spring DeferredResult实现长轮询,纵享新丝滑让你体验丝滑般的感觉》

(4)「待拟定」《Spring Boot使用Spring Callable实现长轮询》

(5)「待拟定」…

这一节我们先来看看《Spring Boot使用Spring DeferredResult实现长轮询,纵享新丝滑让你体验丝滑般的感觉》。

一、初识Spring DeferredResult

1.1 DeferredResult是什么?

         从Spring 3.2开始引入了DeferredResult,有助于将长时间运行的计算从http-worker线程卸载到单独的线程。

尽管另一个线程将占用一些资源来进行计算,但同时不会阻止工作线程,并且可以处理传入的客户端请求。

         DeferredResult:deferred(推迟、延缓)、result(结果),延迟结果,这是一个异步处理类,使用DeferredResult能够实现非阻塞的REST。

1.2 DeferredResult如何使用

         使用起来很简单,只需要new一个DeferredResult对象即可,然后进行返回,如下:

Spring Boot使用Spring DeferredResult实现长轮询,纵享新丝滑让你体验丝滑般的感觉 - 第414篇_第1张图片

         客户端请求映射到控制器方法返回值为DeferredResult时,会立即释放Tomcat线程并将请求挂起,直到调用setResult()方法或者超时,才会响应客户端请求。

         所以我们可以把复杂的代码另起一个线程进行处理,处理结果使用deferredResult.setResult()进行设置,至此请求相应给前端,请求结束。

二、深入Spring DeferredResult

2.1 例子说明

         接下里我们会使用一个小栗子来演示使用DeferredResult的异步处理来实现长轮询。

         对于这个例子先总体的说明下:

(1)有一个页面会使用ajax定时的请求后台,5秒一请求,看是否有新的信息发布。

(2)后端接收到请求之后会使用DeferredResult的异步处理请求,如果此时没有新的信息的话,那么等待超时。

(3)打开新的一个窗口,调用发布新的消息的请求发布新消息。

(4)此时ajax定时请求的页面,应该会及时的显示新的信息。

2.2 环境说明

(1)OS:Mac OS

(2)开发工具:IntelliJ Idea

(3)JDK:1.8

(4)Spring Boot:2.6.1

2.3 开发步骤

(1)构建一个基本的Spring Boot框架

(2)构建一个发布请求的Controller

(3)构建一个页面定时请求后台的Controller

(4)启动测试

2.4 开发实战

2.4.1构建一个基本的Spring Boot框架

         使用开发工具构建一个基本的Spring Boot项目,这一步没啥好说的,

2.4.2构建一个发布请求的Controller

         我们先看下Controller的代码,然后再解释核心部分的代码:

package com.kfit.springbootlongpollingdemo.test;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.context.request.async.DeferredResult;import java.util.Date;import java.util.Random;import java.util.concurrent.TimeUnit;/** * Spring DeferredResult * * @author 悟纤「公众号SpringBoot」 * @date 2022-01-12 * @slogan 大道至简 悟在天成 */@RestControllerpublic class SpringDeferredResultController {    @GetMapping("/handleReqDefResult")    public DeferredResult handleReqDefResult(){        long timeoutValue = 4700;//超时时间.        DeferredResult deferredResult = new DeferredResult<>(timeoutValue);        new Thread(){            @Override            public void run() {                //执行耗时的逻辑                try {                    //休眠n秒钟进行模拟业务代码.                     TimeUnit.SECONDS.sleep(new Random().nextInt(7));                } catch (InterruptedException e) {                    e.printStackTrace();                }                //返回结果.                deferredResult.setResult("love ~ "+new Date());            }        }.start();        return deferredResult;    }}

说明:

(1)使用DeferredResult定义了一个超时时间。

(2)这里的返回值是DeferredResult类型。

(3)开启了一个线程模拟业务的复杂流程,当处理完成之后使用deferredResult.setResult("love ~ "+new Date()); 返回数据,这里是模拟了一个数据,并不是用户进行设置的,先来个简单版本,待会再使用优化。

3.4.3构建一个页面定时请求后台的Servlet

。。。。。。。。。。。。。。。。。

版权原因,完整文章,请参考如下:Spring Boot使用Spring DeferredResult实现长轮询,纵享新丝滑让你体验丝滑般的感觉 - 第414篇

你可能感兴趣的:(框架,spring,spring,boot,java)