SpringBoot集成自定義線程池和異常處理的兩種方式
一.Spring Boot 集成自定義線程池
在 Spring Boot 中,通過 @Configuration 配置 Bean,并結(jié)合 @Async 注解或手動注入 ThreadPoolTaskExecutor,可實現(xiàn)聲明式異步調(diào)用。
1、配置自定義線程池
創(chuàng)建配置類,定義 ThreadPoolTaskExecutor Bean,確保參數(shù)可控且線程命名規(guī)范。
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-");
// 拒絕策略:由調(diào)用線程執(zhí)行,起到背壓作用
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
2、使用 @Async 實現(xiàn)聲明式異步
在 Service 層方法上添加 @Async("bizTaskExecutor"),指定使用上述自定義線程池。
注意:
- 啟動類需添加
@EnableAsync。 - 異步方法必須在另一個類中調(diào)用(自調(diào)用無效),因為 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 中編排異步結(jié)果
在 Controller 中注入 Service,利用 CompletableFuture 組合多個異步任務(wù)的結(jié)果。
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 {
// 并行發(fā)起兩個異步請求
CompletableFuture<String> userFuture = orderService.queryUserAsync();
CompletableFuture<String> orderFuture = orderService.queryOrderAsync();
// 等待所有任務(wù)完成并合并結(jié)果
CompletableFuture.allOf(userFuture, orderFuture).join();
return "用戶: " + userFuture.get() + ", 訂單: " + orderFuture.get();
}
}
4、關(guān)鍵注意事項
- 返回值類型:
@Async方法若需返回結(jié)果,必須返回CompletableFuture<T>或Future<T>,否則調(diào)用方無法獲取返回值。 - 異常處理:異步方法中的異常不會直接拋出到 Controller。建議配置全局
AsyncUncaughtExceptionHandler或在CompletableFuture鏈中處理。 - 事務(wù)問題:
@Async方法默認(rèn)不在主事務(wù)中運行。若需事務(wù),需在異步方法內(nèi)部單獨開啟@Transactional。
二.Spring Boot 異步全局異常處理
在 Spring Boot 中,@Async 方法的異常無法被 Controller 的 @ExceptionHandler 捕獲。需配置 AsyncUncaughtExceptionHandler 進行統(tǒng)一兜底,防止異常靜默丟失。
1、自定義異常處理器
實現(xiàn) AsyncUncaughtExceptionHandler 接口,記錄日志或發(fā)送告警。
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("異步任務(wù)異常 - 方法: {}, 參數(shù): {}", method.getName(), params, ex);
// 此處可集成監(jiān)控告警(如 Sentry/Prometheus)
}
}
2、注冊到 Spring 容器
在配置類中重寫 getAsyncExecutor 和 getAsyncUncaughtExceptionHandler 方法。
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,需在鏈?zhǔn)秸{(diào)用末尾添加 exceptionally 或 handle,確保業(yè)務(wù)級異常被捕獲。
future.thenApply(res -> process(res))
.exceptionally(ex -> {
log.error("業(yè)務(wù)處理失敗", ex);
return defaultResult; // 返回默認(rèn)值,防止鏈路中斷
});
4、核心區(qū)別總結(jié)
| 場景 | 異常捕獲方式 | 適用情況 |
|---|---|---|
| @Async 無返回值 | AsyncUncaughtExceptionHandler | 簡單通知、日志記錄等“發(fā)了就不管”的場景。 |
| CompletableFuture | .exceptionally() / .handle() | 需要獲取結(jié)果、進行業(yè)務(wù)補償或降級的場景。 |
| Controller 層 | @RestControllerAdvice | 無效。無法捕獲異步線程拋出的異常。 |
以上就是SpringBoot集成自定義線程池和異常處理的兩種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot集成自定義線程池和異常處理的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java RSA加密工具類的設(shè)計與實現(xiàn)詳解
RSA算法是一種常用的非對稱加密算法,這篇文章主要為大家詳細(xì)介紹了如何通過Java編寫一個RSA加密工具類,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
用html css javascript打造自己的RIA圖文教程
用html&css&javascript打造自己的RIA之一,包括了配置等2009-07-07
Spring事務(wù)執(zhí)行流程及如何創(chuàng)建事務(wù)
這篇文章主要介紹了Spring事務(wù)執(zhí)行流程及如何創(chuàng)建事務(wù),幫助大家更好的理解和學(xué)習(xí)使用spring框架,感興趣的朋友可以了解下2021-03-03

