Spring WEB 创建异步请求支持线程池

编程教程 > Java > Spring (14) 2025-09-15 13:13:04

概述

前面讲解了Java普通项目如何创建线程池,使用的是java.util.concurrent.ThreadPoolExecutor jdk自带线程池对象。

Spring Mvc/ Spring boot web项目中,请使用spring 实现的线程池,保证在其更好的在spring web 处理异步线程。

 

WebMvcConfigurer.configureAsyncSupport 是 Spring Framework 中用于配置异步请求处理支持的一个方法。

当你在 Spring MVC 应用中想要支持异步处理 HTTP 请求时(例如使用 CallableDeferredResultWebAsyncTask 或响应式编程模型如 Mono/Flux),Spring 会使用底层的异步支持机制(如 Servlet 3.0+ 的异步支持)来处理这些请求。

 

configureAsyncSupport 方法允许你自定义这些异步处理的底层行为。你可以在实现 WebMvcConfigurer 接口的配置类中重写这个方法,来设置:

  1. 默认超时时间 (Default Timeout)

    • 通过 configurer.setDefaultTimeout(long timeout) 设置异步操作的默认超时时间(毫秒)。如果异步任务在这个时间内没有完成,将会触发超时处理。
  2. 任务执行器 (Task Executor)
    • 通过 configurer.setTaskExecutor(AsyncTaskExecutor executor) 指定一个自定义的线程池来执行异步任务。默认情况下,Spring 会使用一个简单的 SimpleAsyncTaskExecutor,但在生产环境中,通常建议配置一个更高效的线程池(如 ThreadPoolTaskExecutor)来避免创建过多线程。
  3. 注册 DeferredResult 的拦截器
    • 通过 configurer.registerDeferredResultInterceptors(HandlerInterceptor... interceptors) 注册拦截器,这些拦截器可以在 DeferredResult 的生命周期(如超时、完成、错误)中执行一些自定义逻辑,比如清理资源、记录日志等。
  4. 注册 WebAsyncManager 的拦截器 (较少使用)
    • 通过 configurer.registerCallableInterceptors(AsyncHandlerInterceptor... interceptors)Callable 类型的异步请求注册拦截器。

为什么需要配置?

  • 性能优化:使用自定义的线程池可以更好地控制资源,避免因默认的简单执行器导致的性能瓶颈或线程耗尽。
  • 超时控制:为异步操作设置合理的超时时间,防止请求无限期挂起,影响系统稳定性。
  • 资源管理与监控:通过拦截器在异步任务的各个阶段插入自定义逻辑,便于进行资源清理、日志记录、性能监控等。

 

项目警告

如果项目中出现了下面错误,请务必配置请求线支持程池

2025-09-13T13:09:28.013+08:00  WARN 27620 --- [boot3-ai] [ctor-http-nio-2] s.w.s.m.m.a.RequestMappingHandlerAdapter : !!!
Performing asynchronous handling through the default Spring MVC SimpleAsyncTaskExecutor.
This executor is not suitable for production use under load.
Please, configure an AsyncTaskExecutor through the WebMvc config.
-------------------------------
!!!

 

Spring web线程池创建和配置示例

创建spring 线程池

    @Bean
    public ThreadPoolTaskExecutor taskPool(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(8);
        executor.setMaxPoolSize(16);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(0);
        executor.setThreadNamePrefix("task-pool-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return executor;
    }

自定义线程池配置给webmvc(必须!!!)

创建一个配置类,通过实现接口WebMvcConfigurer 并重写方法configureAsyncSupport 配置自定义的spring线程池


import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class WebMvcConfig  implements WebMvcConfigurer {
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(taskPool());
        configurer.setDefaultTimeout(60000);//60s
    }
    @Bean
    public ThreadPoolTaskExecutor taskPool(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(8);
        executor.setMaxPoolSize(16);
        executor.setQueueCapacity(1000);
        executor.setKeepAliveSeconds(0);
        executor.setThreadNamePrefix("task-pool-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        return executor;
    }
    @PreDestroy
    public void preDestroy(){
        taskPool().shutdown();
    }
}

 

示例2

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        // 设置默认超时时间为30秒
        configurer.setDefaultTimeout(30_000);
        // 配置一个自定义的线程池
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(50);
        executor.setThreadNamePrefix("async-");
        executor.initialize();
        configurer.setTaskExecutor(executor);
        // 注册一个 DeferredResult 拦截器
        configurer.registerDeferredResultInterceptors(new MyDeferredResultInterceptor());
    }
}

总结WebMvcConfigurer.configureAsyncSupport 是一个强大的钩子方法,让你能够精细地控制 Spring MVC 中异步请求的执行环境、超时策略和生命周期管理,对于构建高性能、高可用的 Web 应用至关重要。

 


评论
User Image
提示:请评论与当前内容相关的回复,广告、推广或无关内容将被删除。

相关文章
概述前面讲解了Java普通项目如何创建线程池,使用的是java.util.concurrent.ThreadPoolExecutor jdk自带线程池对象。Sp
普通项目中使用Java线程池,创建线程池参考示例代码 ThreadPoolExecutor threadPoolExecutor = new ThreadPoo
Spring 注解默认方案启用异步支持import org.springframework.boot.SpringApplication;import org.
WebMvcConfigurer 中的 configureAsyncSupport 和 @EnableAsync 注解虽然都涉及“异步”,但它们服务于不同的异步
Java基础多线程之主线程等待子线程结束,Java基础编程之多线程入门学习篇。主要讲解几种方法来实现Java多线程中主线程等待子线程结束的最快方式。
线程池创建 /** * 队列用线程 * @return */ @Bean(name = "queuePool") public Thread...
java多线程编程_java多线程安全_java多线程实现安全锁CAS机制,CAS在java多线程中相当于数据库的乐观锁,synchronized相当于数据库的乐观锁。
ThreadPoolExecutor 实现的拒绝策略有以下几种AbortPolicyDiscardPolicyDiscardOldestPolicyCaller
线程安全是像Java这样的语言/平台中的类的重要质量,我们经常在线程之间共享对象。由于缺乏线程安全性而导致的问题非常难以调试,因为它们零星且几乎不可能有意再现。你如何测试你的对象以确保它们是线程...
Spring作为一个IOC/DI容器,帮助我们管理了许许多多的“bean”。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。
spring boot 2.0 入门之单元测试多线程。spring boot 2.0 项目含多线程异步处理业务单元测试执行主线程结束不等待子线程结束。
Java多线程生命周期
摘要上节解决了单一线程的 trace id 传递,如果子线程和线程池怎么办呢,还有 rpc 远程调用,怎么玩呢?我们在做项目中肯定有很多时候希望通过异步的方式来
本文将讲述什么是自旋锁?自旋锁的使用场景,什么情况适合使用自旋锁?Java 怎么使用自旋锁?