Spring @Async的異常處理
阿新 • • 發佈:2017-10-28
如何 readn www. cat 發生 implement tle ted 操作
樓主在前面的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 }
Spring @Async的異常處理