Spring Boot 2.x实战51 - Spring Web MVC 23 - 异步请求(Servlet 3.0 异步返回-Callable)

5. 异步请求

当一个web请求到达了Servlet容器时,Servlet线程将被阻碍直至处理执行完成。这种阻碍称为同步,我们需要通过一些方式来降低Servlet容器的负载。

5.1 Servlet 3.0 异步返回

Spring MVC支持Servlet 3.0提供的异步支持,它将web请求的处理放在另外一个线程中。我们由另外的线程来处理耗时的任务,而让Servlet线程被释放去处理另外的web请求,而不是阻碍Servlet线程。此时的返回(response)还是打开的,当处理完成后,将处理结果返回给客户端。

我们无需与Servlet API进行交互,Spring MVC支持DeferredResultCallable作为控制器方法返回值提供单个值的异步返回。

Callable:当异步运算结束后返回结果;

DeferredResult: 结果由另外一个线程在稍后异步运算后返回。

5.1.1Callable

我们只需将控制器的方法的返回值设置为java.util.concurrent.Callable即可,它会使用Spring MVC提供的TaskExecutorSimpleAsyncTaskExecutor,线程名以MvcAsync打头)来控制线程。

我们定义TaskService用来演示处理:

@Service
@Slf4j
public class TaskService {

    public String callableTask() throws InterruptedException{
        Thread.sleep(5000); 
        log.info("+++++Callable数据返回+++++");
        return "result from Callable";
    }
}

定义控制器演示异步任务:

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

    private TaskService taskService;

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

    @GetMapping("/callable")
    public Callable<String> callable(){
        log.info("+++++servlet线程已释放+++++"); // 1
        return taskService::callableTask; // 2
    }
 
  1. 控制器方法直接将servlet线程释放

  2. Callable是函数接口,不接受参数而产生返回值,属于Supplier,我们的callableTask方法符合Callable的定义需要。当然我们返回值也可以用Lambda表达式:

    return () -> {
        Thread.sleep(5000);
        log.info("+++++Callable数据返回+++++");
        return "result from Callable";
    };
    

Chrome地址栏访问https://localhost:8443/async/callable,并打开Chrome控制台。
Spring Boot 2.x实战51 - Spring Web MVC 23 - 异步请求(Servlet 3.0 异步返回-Callable)_第1张图片
这时IDE控制台提示我们使用需要定制线程执行器:
Spring Boot 2.x实战51 - Spring Web MVC 23 - 异步请求(Servlet 3.0 异步返回-Callable)_第2张图片
那我们通过实现WebMvcConfigurer接口的configureAsyncSupport方法,Spring MVC给我们提供了AsyncSupportConfigurer来配置,包含配置TaskExecutor

@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(callableTaskExecutor());
}

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

再次访问https://localhost:8443/async/callable,IDE控制台的线程已经切换成我们定制的线程池了。
在这里插入图片描述

新书推荐:

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

Spring Boot 2.x实战51 - Spring Web MVC 23 - 异步请求(Servlet 3.0 异步返回-Callable)_第3张图片
主要包含目录有:

第一章 初识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)
多谢大家支持。

你可能感兴趣的:(Spring,Boot2.x实战全集,Spring,Boot2.x实战,-,Spring,MVC)