当前位置: 首页 > news >正文

Spring Boot 集成自定义线程池和异常处理

Spring Boot 集成自定义线程池和异常处理

  • 1.Spring Boot 集成自定义线程池
    • 一、配置自定义线程池
    • 二、使用 @Async 实现声明式异步
    • 三、Controller 中编排异步结果
    • 四、关键注意事项
  • 2.Spring Boot 异步全局异常处理
    • 一、自定义异常处理器
    • 二、注册到 Spring 容器
    • 三、CompletableFuture 的异常处理
    • 四、核心区别总结

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

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

一、配置自定义线程池

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

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importjava.util.concurrent.ThreadPoolExecutor;@ConfigurationpublicclassAsyncConfig{@Bean("bizTaskExecutor")publicThreadPoolTaskExecutortaskExecutor(){ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);executor.setKeepAliveSeconds(60);executor.setThreadNamePrefix("biz-async-");// 拒绝策略:由调用线程执行,起到背压作用executor.setRejectedExecutionHandler(newThreadPoolExecutor.CallerRunsPolicy());executor.initialize();returnexecutor;}}

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

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

注意:

  1. 启动类需添加@EnableAsync
  2. 异步方法必须在另一个类中调用(自调用无效),因为 Spring AOP 基于代理。
importorg.springframework.scheduling.annotation.Async;importorg.springframework.stereotype.Service;importjava.util.concurrent.CompletableFuture;@ServicepublicclassOrderService{@Async("bizTaskExecutor")publicCompletableFuture<String>queryUserAsync(){try{Thread.sleep(1000);}catch(InterruptedExceptione){}returnCompletableFuture.completedFuture("User_1001");}@Async("bizTaskExecutor")publicCompletableFuture<String>queryOrderAsync(){try{Thread.sleep(1200);}catch(InterruptedExceptione){}returnCompletableFuture.completedFuture("Order_List");}}

三、Controller 中编排异步结果

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

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.concurrent.CompletableFuture;@RestControllerpublicclassOrderController{@AutowiredprivateOrderServiceorderService;@GetMapping("/order/detail")publicStringgetOrderDetail()throwsException{// 并行发起两个异步请求CompletableFuture<String>userFuture=orderService.queryUserAsync();CompletableFuture<String>orderFuture=orderService.queryOrderAsync();// 等待所有任务完成并合并结果CompletableFuture.allOf(userFuture,orderFuture).join();return"用户: "+userFuture.get()+", 订单: "+orderFuture.get();}}

四、关键注意事项

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

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

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

一、自定义异常处理器

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

importorg.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;importlombok.extern.slf4j.Slf4j;importjava.lang.reflect.Method;@Slf4jpublicclassCustomAsyncExceptionHandlerimplementsAsyncUncaughtExceptionHandler{@OverridepublicvoidhandleUncaughtException(Throwableex,Methodmethod,Object...params){log.error("异步任务异常 - 方法: {}, 参数: {}",method.getName(),params,ex);// 此处可集成监控告警(如 Sentry/Prometheus)}}

二、注册到 Spring 容器

在配置类中重写getAsyncExecutorgetAsyncUncaughtExceptionHandler方法。

importorg.springframework.context.annotation.Configuration;importorg.springframework.scheduling.annotation.AsyncConfigurer;importorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;importjava.util.concurrent.Executor;@ConfigurationpublicclassAsyncConfigimplementsAsyncConfigurer{@OverridepublicExecutorgetAsyncExecutor(){ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);executor.setThreadNamePrefix("biz-async-");executor.initialize();returnexecutor;}@OverridepublicAsyncUncaughtExceptionHandlergetAsyncUncaughtExceptionHandler(){returnnewCustomAsyncExceptionHandler();}}

三、CompletableFuture 的异常处理

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

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

四、核心区别总结

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

相关文章:

  • css中实现三角形的一些方法
  • 智慧教育平台电子课本下载工具:让教学资源触手可及
  • Proxy - KD 新方法:突破黑盒大语言模型知识蒸馏限制,性能超传统白盒技术!
  • 别再用fail2ban了?试试Linux系统自带的账户锁防暴力破解神器faillock
  • 太强了!输入关键词,这几款AI论文工具就能帮你搞定毕业论文
  • 霞鹜文楷:当传统书法美学遇见现代开源代码
  • 如何在5分钟内搭建专业的无人机强化学习环境:gym-pybullet-drones完整指南
  • AutoGen框架深度拆解:群聊、可定制发言人与嵌套Agent的编程范式
  • CTFshow PWN入门实战:手把手教你用pwntools搞定pwn24(含shellcraft模块详解)
  • 如何用Sunshine搭建终极免费游戏串流系统:5分钟实现跨平台游戏自由
  • 解锁Axure中文界面:3步实战教程解决原型设计语言障碍
  • 为什么选择PiliPlus:打造纯净B站体验的终极解决方案
  • 霞鹜文楷:为什么这款开源中文字体成为开发者与设计师的新宠?
  • Markdown Viewer:浏览器中高效渲染Markdown文件的智能解决方案
  • AP-15 DDS在AUTOSAR AP中的集成实战 - ara::com DDS绑定、SOME/IP vs DDS深度对比与安全机制
  • 23 RAG 为什么答不准:召回、分块、排序的常见坑
  • WaveTools鸣潮工具箱:如何一键解锁120FPS高帧率游戏体验
  • 告别TrackBar!用这个开源控件5分钟搞定C# WinForm酷炫仪表盘
  • 保姆级教程:用Frida-Dexdump一键脱掉360加固的壳(附最新脚本)
  • 会小汪观察|第44届康博会圆满收官,重塑西部康养产业新格局
  • 如何3步完成Nintendo Switch大气层自定义固件安装:新手终极教程
  • 工信局如何识别产业链中的断点与卡脖子环节?
  • 参数引发的复制中断:max_binlog_cache_size 导致 SQL 线程异常的复现与分析
  • 达梦DMRMAN备份集校验:别等数据丢了才检查!手把手教你用CHECK命令给备份上个‘保险’
  • SAP顾问必看:手把手教你用SNOTE打补丁,从下载SAR文件到撤回Note全流程避坑
  • 【小白向】虾壳云一键部署完整实操,低配电脑也能流畅运行 OpenClaw v2.7.9 数字员工(最新安装包)
  • Windows系统文件ActivationClient.dll丢失找不到问题解决
  • Three.js 3D饼图教程
  • 电池回收真的还能闭环吗? - 蓝色星球
  • 如何使用DevStore?3分钟完成OpenEuler开发工具一键部署