我有一个要从异步运行作业的类。为此,我有以下代码:
@Resource
private SimpleJobLauncher jobLauncher;
@PostConstruct
public void initLauncher(){
jobLauncher.setTaskExecutor(taskExecutor());
}
但是,在某些情况下,我需要同步执行此操作。因此,我所做的是添加了以下变量:
@Resource
private SimpleJobLauncher synchronousJobLauncher;
我希望不会有taskExecutor
使其同步。然后,我将synchronousJobLauncher
传递到我想同步执行操作的地方。但是,使用synchronousJobLauncher
给我的错误与使用异步错误时的错误相同,这使我相信您不能像我尝试的那样两次自动装配相同的变量。如果我不执行代码的@PostConstruct
部分,那么即使我认为它们使用的是不同的工作启动器,同步部分也可以像我期望的那样工作,而不是异步部分。
有什么想法吗?我尝试使用@Resource
注释代替@Autowired
。
答案 0 :(得分:0)
我没有使用过SimpleJobLaunchers,但是通常在Spring中,我总是使用@Async
注释,这使异步执行变得非常简单。您要做的就是将注释@EnableAsync
添加到任何配置文件中,就像下面的注释一样。
@Configuration
@EnableAsync
public class MvcConfig extends WebMvcConfigurerAdapter { ... }
现在,所有关于将@Async
添加到将异步运行的任何方法中。
@Component
class AsyncTask {
@Async
public Future<String> run() throws InterruptedException {
return new AsyncResult<String>("return value");
}
}
如果要等待结果,可以执行以下操作。
public void callAsyncTask() {
try {
Future<String> future = asyncTask.run();
// Do some other things while the async task is running.
// future.get() will block the function and wait for the result.
String asyncResult = future.get();
} catch(InterruptedException e) {
e.printStackTrace();
// Do something else.
}
}
希望这会有所帮助。我知道您所要求的并不直接,但是也许这种解决方案可以解决您的问题。
答案 1 :(得分:0)
您可以创建两个作业启动器(一个同步启动器和一个异步启动器),然后使用限定符注入所需的启动器。默认情况下,SimpleJobLauncher
使用同步任务执行器,因此您仅需要为异步任务执行器配置任务执行器。这是一个示例:
@Bean
public SimpleJobLauncher synchronousJobLauncher() {
return new SimpleJobLauncher();
}
@Bean
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
@Bean
public SimpleJobLauncher asynchronousJobLauncher() {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setTaskExecutor(threadPoolTaskExecutor());
return jobLauncher;
}
然后,根据需要,用@Qualifier("synchronousJobLauncher")
或@Qualifier("asynchronousJobLauncher")
注入所需的作业启动器。
希望这会有所帮助。