Spring @Async的异常处理

楼主在前面的2篇文章中,分别介绍了Java子线程中通用的异常处理,以及Spring web应用中的异常处理。链接如下:

Java子线程中的异常处理(通用)

Spring web应用中的异常处理

今天,要写的是被Spring @Async注解的方法中的异常处理方法。

 

通常,如果我们要在程序中做一个耗时的操作(例如调用其他外部模块),一般会通过异步的方式执行。

有这2种方法:

  • 自行生成线程池ThreadPoolExecutor,提交任务执行
  • 更方便地,使用Spring @Async注解,修饰在需要异步执行的方法上

对于第一种方法的异常处理,楼主已经在“Java子线程中的异常处理(通用)”这篇文章中介绍了,也就是提交任务后获取到Future对象,通过future.get()获取返回值的时候能够捕获到ExcecutionException。

对于Spring @Async注解的方法,如何进行异常处理呢?楼主想到了2种方法。

解决办法

方法一:配置AsyncUncaughtExceptionHandler(对于无返回值的方法)

通过AsyncConfigurer自定义线程池,以及异常处理。

复制代码
 1 @Configuration
 2 @EnableAsync
 3 public class SpringAsyncConfiguration implements AsyncConfigurer {
 4     private static final Logger logger = LoggerFactory.getLogger(getClass());
5 @Bean 6 @Override 7 public Executor getAsyncExecutor() { 8 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 9 executor.setCorePoolSize(8); 10 executor.setMaxPoolSize(16); 11 executor.setQueueCapacity(64); 12 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 13 executor.setThreadNamePrefix("SpringAsyncThread-"); 14 15 return executor; 16 } 17 18 @Override 19 public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 20 return new SpringAsyncExceptionHandler(); 21 } 22 23 class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { 24 @Override 25 public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { 26 logger.error("Exception occurs in async method", throwable.getMessage()); 27 } 28 } 29 30 }
复制代码

方法二:通过AsyncResult捕获异常(对于有返回值的方法)

如果异步方法有返回值,那就应当返回AsyncResult类的对象,以便在调用处捕获异常。

因为AsyncResult是Future接口的子类,所以也可以通过future.get()获取返回值的时候捕获ExcecutionException。

异步方法:

复制代码
@Service
public class AsyncService {

    @Async
    public AsyncResult<String> asyncMethodWithResult() {
        // do something(可能发生异常)

        return new AsyncResult("hello");
    }

}
复制代码

调用处捕获异常:

复制代码
 1 public class Test {
 2 
 3     private Logger logger = LoggerFactory.getLogger(getClass());
 4 
 5     @Autowired
 6     AsyncService asyncService;
 7 
 8     public void test() {
 9         try {
10             Future future = asyncService.asyncMethodWithResult();
11             future.get();
12         } catch (ExecutionException e) {
13             logger.error("exception occurs", e);
14         } catch (InterruptedException e) {
15             logger.error("exception occurs", e);
16         }
17     }
18 
19 }
复制代码

 

posted @   Java烘焙师  阅读(11278)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示

目录导航

解决办法
方法二:通过AsyncResult捕获异常(对于有返回值的方法)