簡體   English   中英

如何按特定順序運行Spring Batch Jobs(Spring Boot)?

[英]How to run Spring Batch Jobs in certain order (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] o.s.b.c.c.a.DefaultBatchConfigurer: 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"); 或做Autowired在主類此JobLauncher bean並通過調用,啟動特定的工作順序的特定順序jobLauncher.run(job, jobParameters)

您可以從步驟#2初始化的上下文中獲取特定的job實例。

您始終可以使用任何有序集合將作業放在那里,並通過迭代該集合來啟動作業。

4.只要您的JobLauncher配置為同步,即上述技術有效,即主線程等待jobLauncher.run()調用完成,這是jobLauncher的默認行為。

如果已將jobLauncher定義為使用AsyncTaskExecutor,則將並行啟動作業,並且不會保持順序排序。

希望能幫助到你 !!

編輯:

我正在嘗試使用Stephane Nicoll指出的@Order注釋,它似乎只能幫助創建一個Ordered的作業集合,並且您可以按順序迭代並啟動作業。

這個下面的組件給我指定的順序,

@Component
public class MyJobs {
    @Autowired
    private List<Job> jobs;

    public List<Job> 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();
}

有關更多詳細信息,請參閱@Orderjavadoc

以下是解決方案的說明。

這太奇怪了,看起來我們正在破解這個過程。

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());
    }

}

我沒有足夠的代表發表評論。 但您是否嘗試過以您想要的順序手動啟動作業?

您需要在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] o.s.b.c.l.support.SimpleJobLauncher      : Job: [firstJob] launched with the following parameters: ...
2016-12-30 09:48:36.457  INFO 144860 --- [cTaskExecutor-1] o.s.b.c.l.support.SimpleJobLauncher      : Job: [firstJob] completed with the following parameters: ...
2016-12-30 09:48:36.478  INFO 144860 --- [cTaskExecutor-2] o.s.b.c.l.support.SimpleJobLauncher      : Job: [secondJob] launched with the following parameters: ...
2016-12-30 09:48:36.478  INFO 144860 --- [cTaskExecutor-2] o.s.b.c.l.support.SimpleJobLauncher      : Job: [secondJob] completed with the following parameters: ...
2016-12-30 09:48:36.508  INFO 144860 --- [cTaskExecutor-3] o.s.b.c.l.support.SimpleJobLauncher      : Job: [thirdJob] launched with the following parameters: ...
2016-12-30 09:48:36.508  INFO 144860 --- [cTaskExecutor-3] o.s.b.c.l.support.SimpleJobLauncher      : Job: [thirdJob] completed with the following parameters: ...

如果你的一份工作依賴於第二份工作,那么就做這樣的事情吧。

@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<Person> reader, ItemProcessor<Person, Person> processor, ItemWriter<Person> writer) {
        return steps.get("step1")
            .<Person, Person> chunk(10)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
    }

    @Bean
    protected Step step2(Tasklet tasklet) {
        return steps.get("step2")
            .tasklet(tasklet)
            .build();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM