自动装配多个SimpleJobLaunchers

时间:2018-11-01 14:35:20

标签: java spring spring-batch

我有一个要从异步运行作业的类。为此,我有以下代码:

@Resource
private SimpleJobLauncher jobLauncher;

@PostConstruct
public void initLauncher(){
    jobLauncher.setTaskExecutor(taskExecutor());
}

但是,在某些情况下,我需要同步执行此操作。因此,我所做的是添加了以下变量:

@Resource
private SimpleJobLauncher synchronousJobLauncher;

我希望不会有taskExecutor使其同步。然后,我将synchronousJobLauncher传递到我想同步执行操作的地方。但是,使用synchronousJobLauncher给我的错误与使用异步错误时的错误相同,这使我相信您不能像我尝试的那样两次自动装配相同的变量。如果我不执行代码的@PostConstruct部分,那么即使我认为它们使用的是不同的工作启动器,同步部分也可以像我期望的那样工作,而不是异步部分。

有什么想法吗?我尝试使用@Resource注释代替@Autowired

2 个答案:

答案 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")注入所需的作业启动器。

希望这会有所帮助。