弹簧异步未捕获异常处理程序
@Override
@Async
public void asyncExceptionTest() {
int i=1/0;
}
如何使用Spring Async框架记录此内容,而不必在每个异步方法周围放置 try catch?它似乎没有像正常人一样。DefaultUncaughtExceptionHandler
@Override
@Async
public void asyncExceptionTest() {
int i=1/0;
}
如何使用Spring Async框架记录此内容,而不必在每个异步方法周围放置 try catch?它似乎没有像正常人一样。DefaultUncaughtExceptionHandler
@Async
可以使用自定义方法配置方法,以记录任何引发的异常。Executor
下面的代码实现此模式。任何标记的方法都将使用由方法 返回的 。这将返回 what 负责所有日志记录(在本例中,它只打印单词“CATCH!”,但您可以替换为日志记录。@Async
Executor
public Executor getAsyncExecutor()
HandlingExecutor
@Configuration
@EnableAsync
public class ExampleConfig implements AsyncConfigurer {
@Bean
public Runnable testExec() {
return new TestExec();
}
@Override
public Executor getAsyncExecutor() {
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(7);
executor.setMaxPoolSize(42);
executor.setQueueCapacity(11);
executor.setThreadNamePrefix("MyExecutor-");
executor.initialize();
return new HandlingExecutor(executor);
}
}
public class HandlingExecutor implements AsyncTaskExecutor {
private AsyncTaskExecutor executor;
public HandlingExecutor(AsyncTaskExecutor executor) {
this.executor = executor;
}
@Override
public void execute(Runnable task) {
executor.execute(task);
}
@Override
public void execute(Runnable task, long startTimeout) {
executor.execute(createWrappedRunnable(task), startTimeout);
}
@Override
public Future<?> submit(Runnable task) {
return executor.submit(createWrappedRunnable(task));
}
@Override
public <T> Future<T> submit(final Callable<T> task) {
return executor.submit(createCallable(task));
}
private <T> Callable<T> createCallable(final Callable<T> task) {
return new Callable<T>() {
@Override
public T call() throws Exception {
try {
return task.call();
} catch (Exception e) {
handle(e);
throw e;
}
}
};
}
private Runnable createWrappedRunnable(final Runnable task) {
return new Runnable() {
@Override
public void run() {
try {
task.run();
} catch (Exception e) {
handle(e);
}
}
};
}
private void handle(Exception e) {
System.out.println("CAUGHT!");
}
}
更新:自春季4.1起
从Spring 4.1开始,可以有一个AsyncUncaughtExceptionHandler来获取方法。@Async
void
春季参考文档,第 34.4.5 章 @Async异常管理
...但是,对于 void 返回类型,异常是未捕获的,无法传输。对于这些情况,可以提供 AsyncUncaughtExceptionHandler 来处理此类异常。
默认情况下,仅记录异常。自定义的 AsyncUncaughtExceptionHandler 可以通过 AsyncConfigurer 或 task:annotation-driven XML 元素来定义。
(此功能是在 DD 提出改进请求后引入的:https://jira.spring.io/browse/SPR-8995,请参阅此答案的评论)
春之前 4.1
看起来像如何处理返回方法的异常的缺失功能。(我在参考文献或java文档中找不到任何提示)void
@Async
我能想象到的解决方案:尝试使用AspectJ编写某种包装器,围绕所有记录异常的方法。@Async
对于日志术语,我建议在弹簧错误跟踪器中创建一个 freature 请求。