Java 当未接收返回值的@Async方法引发异常时,将无法捕获出现的异常信息
我使用AsyncConfigurer实现异步配置 代码显示如下:Java 当未接收返回值的@Async方法引发异常时,将无法捕获出现的异常信息,java,spring,asynchronous,Java,Spring,Asynchronous,我使用AsyncConfigurer实现异步配置 代码显示如下: @Slf4j @Configuration @EnableAsync public class AsyncConfiguration implements AsyncConfigurer { @Bean @Override public Executor getAsyncExecutor() { log.warn("-----------------start asyncServi
@Slf4j
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Bean
@Override
public Executor getAsyncExecutor() {
log.warn("-----------------start asyncServiceExecutor----------------");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(64);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("SpringAsyncThread-");
executor.initialize();
// return executor;
return new HandlingExecutor(executor);
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
throwable.printStackTrace();
log.error("Exception occurs in async method", throwable.getMessage());
}
}
}
在这一点上,我有一个异步方法
schedulingService.acceptTask(任务);这是一个返回值为ListenableFuture并由@Async标记的方法
@PostMapping("processing")
public RestResult<Boolean> acceptTask(@RequestBody Task task) {
log.error(
"HPC服务接到任务处理-task的linkId:{},rootId{}",
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
schedulingService.acceptTask(task);
return RestResult.success(true);
}
@PostMapping("wait/processing")
public RestResult<Boolean> acceptTaskWait(@RequestBody Task task) {
log.error(
"HPC服务接到任务处理-task的linkId:{},rootId{}",
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
try {
return RestResult.success(schedulingService.acceptTask(task).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return RestResult.success(true);
}
}
但它尚未实施。我认为这是一个非常严重的问题。如果有一个好办法,请告诉我如何解决它和这个问题的原因。非常感谢。我使用的springboot版本是2.2.7,因为您已经有了一个新的版本,然后使用它,另一件需要了解的事情是,还支持从控制器方法返回一个未来的
,框架将正确地处理它
在这种情况下,您可能希望将ListenableFuture
转换为CompletableFuture
,并调用然后应用方法来转换结果
@PostMapping(“等待/处理”)
公共未来acceptTaskWait(@RequestBody任务){
日志错误(
“HPC服务接到任务处理-任务的linkId:{},rootId{}“,
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
ListenableFuture结果=schedulingService.acceptTask(任务);
返回result.completable().thenApply(RestResult::success);
}
由于您已经有了一个,然后使用它,另一件需要意识到的事情是,从控制器方法返回一个未来的
也是受支持的,并且框架将正确地处理它
在这种情况下,您可能希望将ListenableFuture
转换为CompletableFuture
,并调用然后应用方法来转换结果
@PostMapping(“等待/处理”)
公共未来acceptTaskWait(@RequestBody任务){
日志错误(
“HPC服务接到任务处理-任务的linkId:{},rootId{}“,
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
ListenableFuture结果=schedulingService.acceptTask(任务);
返回result.completable().thenApply(RestResult::success);
}
async没有在这里添加任何内容。您直接对结果调用get()。所以你基本上增加了很多复杂性,但没有得到任何东西。当然,我知道异步get会使它阻塞,失去异步的意义。我的问题是,我需要这个方法是一个带有返回值的异步方法,如果我不接受这个返回值,这个异步方法的异常也可以被捕获并打印出来。同时,我必须调用此方法来执行同步响应。当然,这次我肯定会打印异常,但问题是我想要捕获的是有一个返回值,但它尚未被处理。返回值时发生异常只返回未来
,或者如果要执行其他操作,请添加2个回调。1表示正常,1表示不正常。查看或使其成为一个可完成的未来,执行您想要的操作并从方法返回。异步在这里不添加任何内容。您直接对结果调用get()。所以你基本上增加了很多复杂性,但没有得到任何东西。当然,我知道异步get会使它阻塞,失去异步的意义。我的问题是,我需要这个方法是一个带有返回值的异步方法,如果我不接受这个返回值,这个异步方法的异常也可以被捕获并打印出来。同时,我必须调用此方法来执行同步响应。当然,这次我肯定会打印异常,但问题是我想要捕获的是有一个返回值,但它尚未被处理。返回值时发生异常只返回未来
,或者如果要执行其他操作,请添加2个回调。1表示正常,1表示不正常。看到或使其成为一个可完成的未来,做你想做的并从方法中返回。返回未来的控制器不满足我。通过你的第一个回答,我仍然能听到你的未来。addCallback编写了其处理方法,并在出现异常时成功打印出日志,即使我没有接收或处理它,也可以正确打印此异步方法的返回值,但这似乎与@Async和Spring无关。返回Future的控制器不能满足我的要求。通过你的第一个回答,我仍然能听到你的未来。addCallback编写了其处理方法,并在出现异常时成功打印出日志,即使我没有接收或处理它,也可以正确打印此异步方法的返回值,但这似乎与@Async和Spring无关
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
System.out.println("进入异常处理");
return new SpringAsyncExceptionHandler();
}