@Async的异常处理
方法一:配置AsyncUncaughtExceptionHandler(对于无返回值的方法)
通过AsyncConfigurer自定义线程池,以及异常处理。
@Configuration
@EnableAsync
public class SpringAsyncConfiguration implements AsyncConfigurer {
private static final Logger logger = LoggerFactory.getLogger(getClass());
@Bean
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(64);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("SpringAsyncThread-");
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
logger.error("Exception occurs in async method", throwable.getMessage());
}
}
}
方法二:通过AsyncResult捕获异常(对于有返回值的方法)
如果异步方法有返回值,那就应当返回AsyncResult类的对象,以便在调用处捕获异常。
因为AsyncResult是Future接口的子类,所以也可以通过future.get()获取返回值的时候捕获ExcecutionException。
异步方法:
@Service
public class AsyncService {
@Async
public AsyncResult<String> asyncMethodWithResult() {
// do something(可能发生异常)
return new AsyncResult("hello");
}
}
public class Test {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
AsyncService asyncService;
public void test() {
try {
Future future = asyncService.asyncMethodWithResult();
future.get();
} catch (ExecutionException e) {
logger.error("exception occurs", e);
} catch (InterruptedException e) {
logger.error("exception occurs", e);
}
}
}