Spring Boot 2.x实战52 - Spring Web MVC 24 - 异步请求(Servlet 3.0 异步返回-DeferredResult)

本文介绍了如何在Spring Boot 2.x中利用Servlet 3.0的异步处理和 DeferredResult 实现异步请求。通过创建线程执行器和定义控制器方法,展示了在不同线程中计算结果并返回的过程。在浏览器中访问特定URL会触发异步请求,并在另一个URL被访问时返回计算结果。

DeferredResult的结果是由另外一个线程再稍后计算后返回给客户端的。DeferredResult的线程执行器可由CompletableFuture来定制。

同样我们在TaskService定义我们的处理:

@Service
@Slf4j
public class TaskService {
    public String deferredTask() {
        log.info("+++++DeferredResult数据返回+++++");
        return "result from DeferredResult";
    }
}

WebConfiguration定义TaskExecutor

@Bean
public ThreadPoolTaskExecutor deferredTaskExecutor(){
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setThreadNamePrefix("deferred-task-");
    return taskExecutor;
}

定义我们演示的控制器:

@RestController
@RequestMapping("/async")
@Slf4j
public class AsyncController {

    private static Map<Long, DeferredResult<String>> deferredResultMap = new HashMap<>();
    @Autowired
    private TaskExecutor deferredTaskExecutor;

    private TaskService taskService;

    public AsyncController(TaskService taskService) {
        this.taskService = taskService;
    }

    @GetMapping("/{id}/deferred") // 1
    public DeferredResult<String> deferred(@PathVariable Long id) throws InterruptedException {
        log.info("+++++servlet线程已释放+++++");
        DeferredResult<String> deferredResult = new DeferredResult();//2
        deferredResultMap.put(id, deferredResult); // 3
        return deferredResult;  
    }

    @GetMapping("/{id}/invoke-deferred") //4
    public void  invokeDeferred(@PathVariable Long id){
        DeferredResult<String> deferredResult = deferredResultMap.get(id); //5
        CompletableFuture.supplyAsync(taskService::deferredTask, deferredTaskExecutor)
                .whenCompleteAsync((result,throwable) -> deferredResult.setResult(result));//6
        deferredResultMap.remove(id);
    }
}
  1. 定义此控制器方法接受web请求;
  2. 定义DeferredResult<String>变量直接返回,此时Servlet线程已释放;
  3. 将当前DeferredResult<String>放入map中,这个map是类是静态的变量,我们可以在其他地方取出map的内容,map中数据的key为id;
  4. 定义此控制器方法用来演示在稍后另外一个运算的线程;
  5. 从map中获取DeferredResult<String>变量;
  6. 使用CompletableFuture指定运算方法、taskExecutor,当计算完成后通过deferredResult.setResult(result)返回结果。

我们先用浏览器访问https://localhost:8443/async/1/deferred,此时请求一直处于等待状态;然后我们访问https://localhost:8443/async/1/invoke-deferred时,即在稍后另外线程中计算并返回结果,该结果显示在https://localhost:8443/async/1/deferred的页面上。
在这里插入图片描述
IDE控制台显示:
在这里插入图片描述

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html
在这里插入图片描述

主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值