Spring @Async的异常处理
楼主在前面的2篇文章中,分别介绍了Java子线程中通用的异常处理,以及Spring web应用中的异常处理。链接如下:
今天,要写的是被Spring @Async注解的方法中的异常处理方法。
通常,如果我们要在程序中做一个耗时的操作(例如调用其他外部模块),一般会通过异步的方式执行。
有这2种方法:
- 自行生成线程池ThreadPoolExecutor,提交任务执行
- 更方便地,使用Spring @Async注解,修饰在需要异步执行的方法上
对于第一种方法的异常处理,楼主已经在“Java子线程中的异常处理(通用)”这篇文章中介绍了,也就是提交任务后获取到Future对象,通过future.get()获取返回值的时候能够捕获到ExcecutionException。
对于Spring @Async注解的方法,如何进行异常处理呢?楼主想到了2种方法。
解决办法
方法一:配置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
</span><span style="color: #0000ff;">public</span> AsyncResult<String><span style="color: #000000;"> asyncMethodWithResult() {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> do something(可能发生异常)</span> <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> AsyncResult("hello"<span style="color: #000000;">);
}
}

调用处捕获异常:

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);
}
}
}

Spring @Async的异常处理的更多相关文章
- Spring @Async开启异步任务
1. 开启异步 @SpringBootApplication @EnableAsync //开启异步任务 public class Application { @Bean(name="pro ...
- Spring Boot系列二 Spring @Async异步线程池用法总结
1. TaskExecutor Spring异步线程池的接口类,其实质是java.util.concurrent.Executor Spring 已经实现的异常线程池: 1. SimpleAsyncT ...
- spring mvc4:异常处理
前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理: 一.Servlet配置文件修改 <bean id="exceptionResolver" c ...
- 使用Spring MVC统一异常处理实战
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- Spring MVC 统一异常处理
Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...
- 【Spring学习笔记-MVC-15.1】Spring MVC之异常处理=404界面
作者:ssslinppp 异常处理请参考前篇博客:<[Spring学习笔记-MVC-15]Spring MVC之异常处理>http://www.cnblogs.com/sssl ...
- 使用Spring MVC统一异常处理实战<转>
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- Spring @async 方法上添加该注解实现异步调用的原理
Spring @async 方法上添加该注解实现异步调用的原理 学习了:https://www.cnblogs.com/shangxiaofei/p/6211367.html 使用异步方法进行方法调用 ...
- Spring 中的异常处理
工作中遇到这样的同事,问他活干完吗,他说开发好了,结果测试时发现各种异常情况未处理,联调测试时各种未知错误,最后联调完成比他预期的两倍工作量还多.这样的开发如果是新人还可以原谅,如果有工作经验且出现多 ...
随机推荐
- Python3 Tkinter-Pack
1.创建 from tkinter import * root=Tk() print(root.pack_slaves()) Label(root,text='pack').pack() print( ...
- C语言中动态内存的分配(malloc,realloc)
动态内存分配:根据需要随时开辟,随时释放的内存分配方式.分配时机和释放时机完全由程序员决定,由于没有数据声明,这部分空间没有名字.无法像使用变量或数组那样通过变量名或数组名引用其中的数据,只能通过指针 ...
- BluetoothSocket详解
一. BluetoothSocket简介 1. 简介 客户端与服务端 : BluetoothSocket 和 BluetoothServerSocket 类似于Java中的套接字的 Socket 和 ...
- SOA是什么为什么要面向服务编程
SOA(面向服务的架构),Service-Oriented Architecture,面向服务的体系结构. 也就是以服务为核心的架构.这里需要理解什么是服务. 比如你有一个读取通知的方法: publi ...
- 链表相加(Add Two Numbers)
描述: 给定两个非空的链表,表示两个非负整数.数字以相反的顺序存储,每个节点包含一个数字.添加两个数字并将其作为链表返回. 您可以假设两个数字不包含任何前导零,除了数字0本身. 输入:(2 - > ...
- iOS- 移动端Socket UDP协议广播机制的实现
1.前言 什么是UDP协议广播机制? 举一个例, 例如在一群人群中,一个人要找张三,于是你向人群里大喊一声(广播):“谁是张三” 如果它是张三,它就会回应你,在网络中也是一样的. ...
- iOS-tableView刷新指定行,组
/一个section刷新 NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:]; [tableview reloadSections:inde ...
- Scala快速入门-基础
HelloWorld 从HelloWorld开始,使用scala IDE编辑器. 新建scala project 新建scala object 编写HelloWorld run as scala ap ...
- 3dContactPointAnnotationTool开发日志(十四)
貌似每次让用户手动输入文件路径太不人道了,于是参考Unity 实用教程 之 调用系统窗口选择文件或路径增加了让用户浏览文件的功能,点击输入框旁边的+就可以找到文件并加载进来: 貌似调整位置再计 ...
- 3dContactPointAnnotationTool开发日志(四)
没办法,为了能在寝室接着做这玩意只好又在电脑上装一个和实验室版本一样的unity了.虽然打开后UI界面还是一团糟,不过至少要的东西都在,又手动调了调UI界面. 然后把旋转视角功能加上了.鼠标右 ...