spring boot 全局异常处理可以通过实现 asyncuncaughtexceptionhandler 接口来捕获 completablefuture 的异常。具体做法是定义一个配置类,使用 @configuration 和 @enableasync 注解,并在其中注入 taskexceptionhandlingconfigurer(或直接在 asyncconfigurer 中设置),将自定义的 asyncuncaughtexceptionhandler 实例注册到 spring 的异步任务执行器中。这样当 completablefuture 抛出未捕获的异常时,该处理器会被调用,从而避免异常被静默吞掉。

如何为 @Async 方法配置异常处理器
通过实现 AsyncConfigurer 接口并重写 getAsyncUncaughtExceptionHandler 方法,可以指定专门处理 @Async 方法异常的逻辑。在方法内部返回一个实现了 AsyncUncaughtExceptionHandler 的匿名类或 Bean,重写 handleUncaughtException 方法即可记录日志或进行其他处理。这种方式适用于所有由 Spring 管理的异步任务。

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return (throwable, method, params) -> {
System.err.println("Exception in async method: " + method.getName());
throwable.printStackTrace();
};
}
}
如何在全局异常处理中统一捕获 CompletableFuture 异常
对于非 @Async 但使用 CompletableFuture 的场景,可以在业务层通过 exceptionally 或 handle 方法捕获异常,或者利用 WebMvcConfigurer 结合 HandlerExceptionResolver 并不直接适用,因为 CompletableFuture 异常通常发生在异步线程中,不在主请求线程。更通用的做法是在 CompletableFuture 链中显式处理异常,例如使用 exceptionally(e -> ...)。如果希望集中处理,可以创建一个工具类,将所有 CompletableFuture 的异常回调指向同一个处理逻辑。

import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("Simulated error");
});
String result = future.exceptionally(ex -> {
System.out.println("Caught exception: " + ex.getMessage());
return "Default Value";
}).join();
System.out.println("Result: " + result);
}
}
CompletableFuture exceptionally 方法的返回值类型是什么
exceptionally 方法接收一个 Function<throwable extends t></throwable> 类型的参数,并返回一个新的 CompletableFuture<t></t>。当原 CompletableFuture 完成时出现异常,该函数会被调用,其返回值将成为新 CompletableFuture 的结果。如果原 CompletableFuture 正常完成,则忽略该函数。因此,exceptionally 允许你提供一个默认值或替代结果,确保后续操作不会因异常而中断。


















