SpringBoot集成自定义线程池和异常处理的两种方式

 更新时间:2026年06月30日 09:15:30   作者:Listen·Rain  
这篇文章主要介绍了SpringBoot集成自定义线池,详解配置步骤、使用@Async注解实现异步调用,并讨论CompletableFuture异常处理及全局异常捕;SpringBoot异步处理机制与自定义异常处理器配置方法,需要的朋友可以参考下

一.Spring Boot 集成自定义线程池

在 Spring Boot 中,通过 @Configuration 配置 Bean,并结合 @Async 注解或手动注入 ThreadPoolTaskExecutor,可实现声明式异步调用。

1、配置自定义线程池

创建配置类,定义 ThreadPoolTaskExecutor Bean,确保参数可控且线程命名规范。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class AsyncConfig {

    @Bean("bizTaskExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setKeepAliveSeconds(60);
        executor.setThreadNamePrefix("biz-async-");
        // 拒绝策略:由调用线程执行,起到背压作用
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

2、使用 @Async 实现声明式异步

在 Service 层方法上添加 @Async("bizTaskExecutor"),指定使用上述自定义线程池。

注意:

  1. 启动类需添加 @EnableAsync
  2. 异步方法必须在另一个类中调用(自调用无效),因为 Spring AOP 基于代理。
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.CompletableFuture;

@Service
public class OrderService {

    @Async("bizTaskExecutor")
    public CompletableFuture<String> queryUserAsync() {
        try { Thread.sleep(1000); } catch (InterruptedException e) {}
        return CompletableFuture.completedFuture("User_1001");
    }

    @Async("bizTaskExecutor")
    public CompletableFuture<String> queryOrderAsync() {
        try { Thread.sleep(1200); } catch (InterruptedException e) {}
        return CompletableFuture.completedFuture("Order_List");
    }
}

3、Controller 中编排异步结果

在 Controller 中注入 Service,利用 CompletableFuture 组合多个异步任务的结果。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;

@RestController
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/order/detail")
    public String getOrderDetail() throws Exception {
        // 并行发起两个异步请求
        CompletableFuture<String> userFuture = orderService.queryUserAsync();
        CompletableFuture<String> orderFuture = orderService.queryOrderAsync();

        // 等待所有任务完成并合并结果
        CompletableFuture.allOf(userFuture, orderFuture).join();
        
        return "用户: " + userFuture.get() + ", 订单: " + orderFuture.get();
    }
}

4、关键注意事项

  1. 返回值类型:@Async 方法若需返回结果,必须返回 CompletableFuture<T>Future<T>,否则调用方无法获取返回值。
  2. 异常处理:异步方法中的异常不会直接抛出到 Controller。建议配置全局 AsyncUncaughtExceptionHandler 或在 CompletableFuture 链中处理。
  3. 事务问题:@Async 方法默认不在主事务中运行。若需事务,需在异步方法内部单独开启 @Transactional

二.Spring Boot 异步全局异常处理

在 Spring Boot 中,@Async 方法的异常无法被 Controller 的 @ExceptionHandler 捕获。需配置 AsyncUncaughtExceptionHandler 进行统一兜底,防止异常静默丢失。

1、自定义异常处理器

实现 AsyncUncaughtExceptionHandler 接口,记录日志或发送告警。

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;

@Slf4j
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
        log.error("异步任务异常 - 方法: {}, 参数: {}", method.getName(), params, ex);
        // 此处可集成监控告警(如 Sentry/Prometheus)
    }
}

2、注册到 Spring 容器

在配置类中重写 getAsyncExecutorgetAsyncUncaughtExceptionHandler 方法。

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;

@Configuration
public class AsyncConfig implements AsyncConfigurer {

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("biz-async-");
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }
}

3、CompletableFuture 的异常处理

若使用 CompletableFuture,需在链式调用末尾添加 exceptionallyhandle,确保业务级异常被捕获。

future.thenApply(res -> process(res))
      .exceptionally(ex -> {
          log.error("业务处理失败", ex);
          return defaultResult; // 返回默认值,防止链路中断
      });

4、核心区别总结

场景异常捕获方式适用情况
@Async 无返回值AsyncUncaughtExceptionHandler简单通知、日志记录等“发了就不管”的场景。
CompletableFuture.exceptionally() / .handle()需要获取结果、进行业务补偿或降级的场景。
Controller 层@RestControllerAdvice无效。无法捕获异步线程抛出的异常。

以上就是SpringBoot集成自定义线程池和异常处理的两种方式的详细内容,更多关于SpringBoot集成自定义线程池和异常处理的资料请关注脚本之家其它相关文章!

相关文章

  • Java RSA加密工具类的设计与实现详解

    Java RSA加密工具类的设计与实现详解

    RSA算法是一种常用的非对称加密算法,这篇文章主要为大家详细介绍了如何通过Java编写一个RSA加密工具类,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-02-02
  • java在原字符中插入新字符或字符串实例

    java在原字符中插入新字符或字符串实例

    这篇文章主要介绍了java在原字符中插入新字符或字符串实例,具有很好的价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 用html css javascript打造自己的RIA图文教程

    用html css javascript打造自己的RIA图文教程

    用html&css&javascript打造自己的RIA之一,包括了配置等
    2009-07-07
  • java高效读大文件(csv,text)的几种处理方式

    java高效读大文件(csv,text)的几种处理方式

    这篇文章主要给大家介绍了关于java高效读大文件(csv,text)的几种处理方式,Java中处理大文件时,通常需要采取一些特定的策略来避免内存溢出或性能问题,文中通过代码及图片介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • Java利用Picocli开发一个简化命令行工具

    Java利用Picocli开发一个简化命令行工具

    Picocli 是一个强大、易用且功能丰富的 Java 库,用于开发命令行工具,本文我们就来为大家介绍一下Java如何利用Picocli进行命令行简化功能的吧
    2025-03-03
  • Spring事务执行流程及如何创建事务

    Spring事务执行流程及如何创建事务

    这篇文章主要介绍了Spring事务执行流程及如何创建事务,帮助大家更好的理解和学习使用spring框架,感兴趣的朋友可以了解下
    2021-03-03
  • Spring @Lazy注解的定义及详细源码展示

    Spring @Lazy注解的定义及详细源码展示

    @Lazy是Spring延迟初始化Bean的注解,通过推迟实例化时机减少启动时间与内存占用,适用于高成本Bean、条件化延迟及解决循环依赖,但需注意首次使用性能开销与依赖顺序问题,本文给大家介绍Spring @Lazy注解的定义及详细源码展示,感兴趣的朋友一起看看吧
    2025-09-09
  • 基于jvm java内存区域的介绍

    基于jvm java内存区域的介绍

    下面小编就为大家带来一篇基于jvm java内存区域的介绍。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • java实现自定义日期选择器的方法实例

    java实现自定义日期选择器的方法实例

    日期选择器是我们日常开发中经常需要用到的一个功能,下面这篇文章主要给大家介绍了关于利用java实现自定义日期选择器的相关资料,文中给出了详细的示例代码,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2017-10-10
  • Mybatis实现动态建表代码实例

    Mybatis实现动态建表代码实例

    这篇文章主要介绍了Mybatis实现动态建表代码实例,解释一下,就是指根据传入的表名,动态地创建数据库表,以供后面的业务场景使用,
    而使用 Mybatis 的动态 SQL,就能很好地为我们解决这个问题,需要的朋友可以参考下
    2023-10-10

最新评论