java - 将 Java `ExecutorService` 与 Spring `TaskExecutor` 混合使用
问题描述
我有一段我以前在没有 Spring 的情况下使用的 Java 代码,如下所示:
// `Callable` instead of `Runnable` because we need to throw exceptions
public MyTask extends Callable<Void> {
@Override
public Void call() throws Exception { ... }
}
public class MyTasksRunner {
private final ExecutorService executorService;
...
public void run() throws Exception {
List<MyTask> tasks = ...;
var futures = executorService.invokeAll(tasks);
for (var future : futures) {
// Rethrow any exceptions happened in the threads.
future.get();
}
}
}
现在我将这段代码合并到一个启用了异步的更大的 Spring Boot 应用程序中。它配置一个TaskExecutor
,它没有与 相同的接口ExecutorService
。ATaskExecutor
只能运行Runnable
s,不能运行Callable
s。
我可能同时拥有一个TaskExecutor
用于异步 Spring 的 bean,以及另一个ExecutorService
用于MyTasksRunner
代码的 bean。但我想知道如果我想合并这些选项我有什么选择:
- 我可以告诉 Spring 使用
ExecutorService
它的异步内容吗? - 我可以将我的
Callable
代码转换为使用Runnable
s,同时仍然能够从任务中传播异常吗?
我也想过只制作MyTask
一个 Spring 组件并用 注释它@Async
,但我真的不喜欢它使MyTask*
代码与 Spring 绑定。
解决方案
是的,您可以将您的Callable
任务转换Runnable
为我认为您不期望任何返回值。但是有一个条件 - 你不能抛出 Checked Exception 但是你可以继续抛出 Runtime Exception。
另外,是的,您可以如下定义Executor
bean 来注入ExecutorService
@Bean
public Executor taskExecutor() {
ExecutorService executor = Executors.newFixedThreadPool(2);
return executor;
}
如果您没有定义 Executor bean,Spring 会创建SimpleAsyncTaskExecutor
并使用它。
推荐阅读
- arduino - Arduino中的字符串比较
- python - 如何将 JSON 转换为 CSV?
- java - 在 Spring Data JDBC 中绕过 @CreatedDate 和 @LastModifiedDate
- excel - 从非连续单元格复制数据
- flutter - 在 android 5 设备中调试时出现颤振错误
- python - 无法连接 sqlite3 中的两个属性
- ios - SwiftUI,按下时如何更改视图(不使用按钮)颜色?
- javascript - 如何通过拖动角来调整 html5 画布元素的大小并应保持纵横比?
- postgresql - Postgres 复制表分隔符
- vue.js - 如何仅更改默认选择选项的颜色,而不更改 Vue 中的其他选项?