前面的文章写了 @Async 的异步调用,但是没有涉及到异步任务异常如何处理,这个统一来说明一下异步任务的处理方法。
- 对于无返回值的异步任务,配置AsyncExceptionConfig类,统一处理。
- 对于有返回值的异步任务,可以在contoller层捕获异常,进行处理。
1、无返回值方法
- 定义异常捕获配置类AsyncExceptionConfig,配置类里面定义SpringAsyncExceptionHandler 方法实现AsyncUncaughtExceptionHandler 接口。
@Configuration
public class AsyncExceptionConfig implements AsyncConfigurer {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
System.out.println("------我是Async无返回方法的异常处理方法---------");
}
}
}
- 无返回方法增加抛出异常的代码
@Async("piceaTaskExecutor")
@Override
public void asyncTask() throws Exception {
System.out.println("异步线程,线程名:" + Thread.currentThread().getName());
System.out.println("异步处理方法-----start-------");
System.out.println("------------------------在看貂蝉,不要打扰--------------");
String noNum = "sdfdfsd";
//把一个非数字转成数字,抛出异常来测试。
int i = Integer.parseInt(noNum);
Thread.sleep(2000);
System.out.println("异步处理方法------end--------");
}
- 测试方法及结果
浏览器中访问http://localhost:2001/asyncTask
基于Future的异常处理
- 基于Future可以直接修改contoller层捕获异常
@RequestMapping("/asyncTaskFuture")
public String asyncTaskFuture() {
System.out.println("在控制层调用的线程名:"+ Thread.currentThread().getName());
String ret = null;
try {
//异步先执行任务1
Future<String> future = piceaService.asyncTaskFuture();
//异步执行任务2
Future<String> future2 = piceaService.asyncTaskFuture2();
//取任务1的执行结果,设置超时时间
String ret1 = future.get(1, TimeUnit.SECONDS);
//去任务2的执行结果,设置超时时间
String ret2 = future2.get(10,TimeUnit.SECONDS);
//任务1结果+任务2结果
ret = ret1 + "+" + ret2;
//最终返回任何合集
return ret;
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("------我是Async有返回方法的异常处理方法----InterruptedException-----");
} catch (ExecutionException e) {
e.printStackTrace();
System.out.println("------我是Async有返回方法的异常处理方法----ExecutionException-----");
} catch (Exception e) {
e.printStackTrace();
System.out.println("------我是Async有返回方法的异常处理方法----Exception-----");
}
return null;
}
- 测试方法及结果
浏览器中访问http://localhost:2001/asyncTaskFuture
“打” 完收工,这是服务8折券,老板请收好。
其它注意
本文章样例:
工程名:spring-boot-async-3
GitHub:https://github.com/zzyjb/SpringBootLearning
- Web工程Async异步请移步
https://www.jianshu.com/p/7482721e3ac8 - 自定义线程池请移步
https://www.jianshu.com/p/dabd65f617bb - 异步异常处理-本章
https://www.jianshu.com/p/11c78717799b