【异常】Spring @Async的异常处理
温馨提示:
本文最后更新于 2020年08月24日,已超过 1,544 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
楼主在前面的2篇文章中,分别介绍了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 }
正文到此结束