spring boot 全局异常处理无法直接捕获线程池抛出的异常,因为线程池默认在独立线程中执行任务,异常会被吞掉或仅打印到日志。要捕获这些异常,必须为 threadpooltaskexecutor 配置 rejectedexecutionhandler 或使用自定义的 asyncuncaughtexceptionhandler(针对 @async),并在其中手动触发全局异常逻辑或记录日志。

如何配置线程池的拒绝策略来捕获异常
通过实现 RejectedExecutionHandler 接口,可以在任务被拒绝时捕获异常并进行处理。这是处理线程池边界情况的标准做法。

import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class CustomRejectedHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// 尝试运行任务以捕获同步异常
r.run();
} catch (Exception e) {
// 在这里处理异常,例如记录日志或通知全局处理器
System.err.println("Task rejected and threw exception: " + e.getMessage());
}
}
}
// 配置类示例
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setRejectedExecutionHandler(new CustomRejectedHandler());
executor.initialize();
return executor;
}
}
如何使用 AsyncUncaughtExceptionHandler 处理 @Async 方法异常
对于使用 @Async 注解的方法,Spring 提供了 AsyncUncaughtExceptionHandler 接口来处理异步方法执行期间抛出的异常。这比默认的日志输出更可控。

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import java.lang.reflect.Method;
public class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
// 处理异常,例如记录详细日志或发送告警
System.err.println("Async method " + method.getName() + " threw exception: " + ex.getMessage());
ex.printStackTrace();
}
}
// 配置类示例
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncExceptionHandler();
}
}
当线程池队列满且达到最大线程数时会发生什么
当线程池的工作队列已满,且当前线程数已达到最大线程数时,新提交的任务将被拒绝。此时会调用配置的 RejectedExecutionHandler。如果未自定义,默认使用 AbortPolicy,它会抛出 RejectedExecutionException。这个异常不会由 Spring 的全局异常处理器(如 @ControllerAdvice)捕获,因为它发生在异步上下文中。因此,必须在 RejectedExecutionHandler 的实现中显式处理该异常,否则应用可能静默失败或崩溃。











