1. 程式人生 > >Spring @Async的異常處理

Spring @Async的異常處理

如何 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的異常處理