如何按特定顺序运行Spring Batch Jobs(Spring Boot)?

我正在使用Spring Boot开发Spring Batch。

我使用Spring Boot提供的最小配置并定义了一些Jobs(根本没有XML配置)。 但是当我运行应用程序时

SpringApplication.run(App.class, args); 

作业按任意顺序依次执行。

我在@Configuration注释类中以这种方式定义作业,Spring完成其余的工作:

 @Bean public Job requestTickets() { return jobBuilderFactory.get(Config.JOB_REQUEST_TICKETS) .start(stepRequestTickets()) .build(); } 

如何指示框架按特定顺序运行作业?

编辑:这个警告可以提示吗? (也许没什么可比的)

 2016-12-29 17:45:33.320 WARN 3528 --- [main] osbccaDefaultBatchConfigurer: No datasource was provided...using a Map based JobRepository 

1.首先通过在application.properties中指定spring.batch.job.enabled=false来禁用自动作业启动

2.在你的主类中,执行 – ApplicationContext ctx = SpringApplication.run(SpringBatchMain.class, args); 假设您的主类被命名为 – SpringBatchMain.java。

这将初始化上下文而不启动任何作业。

3.Once上下文初始化,你可以做 – JobLauncher jobLauncher = (JobLauncher) ctx.getBean("jobLauncher"); 或者在主类中为此JobLauncher bean执行自动assembly,并通过调用jobLauncher.run(job, jobParameters)以特定的顺序顺序启动特定作业。

您可以从步骤#2初始化的上下文中获取特定的job实例。

您始终可以使用任何有序集合将作业放在那里,并通过迭代该集合来启动作业。

4.只要您的JobLauncher配置为同步,即上述技术有效,即主线程等待jobLauncher.run()调用完成,这是jobLauncher的默认行为。

如果已将jobLauncher定义为使用AsyncTaskExecutor,则将并行启动作业,并且不会保持顺序排序。

希望能帮助到你 !!

编辑:

我正在尝试使用Stephane Nicoll指出的@Order注释,它似乎只能帮助创建Ordered的作业集合,并且您可以按顺序迭代并启动作业。

这个下面的组件给我指定的顺序,

 @Component public class MyJobs { @Autowired private List jobs; public List getJobs() { return jobs; } } 

我能做到, MyJobs myJobs = (MyJobs) ctx.getBean("myJobs"); 在主类中提供bean定义,

 @Bean public MyJobs myJobs() { return new MyJobs(); } 

我可以迭代myJobs并按照@Order注释指定的顺序启动作业。

订购它们。

 @Bean @Order(42) public Job requestTickets() { return jobBuilderFactory.get(Config.JOB_REQUEST_TICKETS) .start(stepRequestTickets()) .build(); } 

有关更多详细信息,请参阅@Order的javadoc 。

我没有足够的代表发表评论。 但是,您是否尝试过以您想要的顺序手动启动作业?

您需要在application.properties中设置spring.batch.job.enabled = false ,以便您的作业不会自动运行。

然后只需使用启动器按您想要的顺序启动作业。

 @RunWith(SpringRunner.class) @SpringBootTest(classes = { TestConfiguration.class, TestDataSourceConfiguration.class, TestBatchConfig.class }) public class JobOrderTest { @Autowired JobLauncher jobLauncher; @Mock Job firstJob; @Mock Job secondJob; @Mock Job thirdJob; @Mock JobParametersValidator jobParametersValidator; @Test public void jobInOrderTest() throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException { when(firstJob.getName()).thenReturn(UUID.randomUUID().toString()); when(secondJob.getName()).thenReturn(UUID.randomUUID().toString()); when(thirdJob.getName()).thenReturn(UUID.randomUUID().toString()); when(firstJob.getJobParametersValidator()).thenReturn(jobParametersValidator); when(secondJob.getJobParametersValidator()).thenReturn(jobParametersValidator); when(thirdJob.getJobParametersValidator()).thenReturn(jobParametersValidator); jobLauncher.run(firstJob, new JobParameters()); jobLauncher.run(secondJob, new JobParameters()); jobLauncher.run(thirdJob, new JobParameters()); } } 

这是输出

 2016-12-30 09:48:36.457 INFO 144860 --- [cTaskExecutor-1] osbclsupport.SimpleJobLauncher : Job: [firstJob] launched with the following parameters: ... 2016-12-30 09:48:36.457 INFO 144860 --- [cTaskExecutor-1] osbclsupport.SimpleJobLauncher : Job: [firstJob] completed with the following parameters: ... 2016-12-30 09:48:36.478 INFO 144860 --- [cTaskExecutor-2] osbclsupport.SimpleJobLauncher : Job: [secondJob] launched with the following parameters: ... 2016-12-30 09:48:36.478 INFO 144860 --- [cTaskExecutor-2] osbclsupport.SimpleJobLauncher : Job: [secondJob] completed with the following parameters: ... 2016-12-30 09:48:36.508 INFO 144860 --- [cTaskExecutor-3] osbclsupport.SimpleJobLauncher : Job: [thirdJob] launched with the following parameters: ... 2016-12-30 09:48:36.508 INFO 144860 --- [cTaskExecutor-3] osbclsupport.SimpleJobLauncher : Job: [thirdJob] completed with the following parameters: ... 

以下是解决方案的说明。

这太奇怪了,看起来我们正在破解这个过程。

spring.batch.job.enabled = FALSE

 @SpringBootApplication @EnableBatchProcessing public class MyApplication { public static void main(String[] args) throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { ConfigurableApplicationContext ctx = SpringApplication.run(MyApplication.class, args); JobLauncher jobLauncher = (JobLauncher) ctx.getBean("jobLauncher"); Job job1= (Job) ctx.getBean("job1"); Job job2= (Job) ctx.getBean("job2"); jobLauncher.run(job1,new JobParameters()); jobLauncher.run(job2,new JobParameters()); } } 

如果你的一份工作依赖于第二份工作,那么就做这样的事情吧。

 @Configuration @EnableBatchProcessing @Import(DataSourceConfiguration.class) public class AppConfig { @Autowired private JobBuilderFactory jobs; @Autowired private StepBuilderFactory steps; @Bean public Job job(@Qualifier("step1") Step step1, @Qualifier("step2") Step step2) { return jobs.get("myJob").start(step1).next(step2).build(); } @Bean protected Step step1(ItemReader reader, ItemProcessor processor, ItemWriter writer) { return steps.get("step1") . chunk(10) .reader(reader) .processor(processor) .writer(writer) .build(); } @Bean protected Step step2(Tasklet tasklet) { return steps.get("step2") .tasklet(tasklet) .build(); } }