how to select which spring batch job to run based on application argument - spring boot java config

[亡魂溺海] 提交于 2019-12-18 02:50:39

问题


I have two independent spring batch jobs in the same project because I want to use the same infrastructure-related beans. Everything is configured in Java. I would like to know if there's a proper way to start the jobs independent based for example on the first java app argument in the main method for example. If I run SpringApplication.run only the second job gets executed by magic. The main method looks like:

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {                
        SpringApplication app = new SpringApplication(Application.class);
        app.setWebEnvironment(false);
        ApplicationContext ctx= app.run(args);              
    }

}

and the two jobs are configured as presented in the Spring Batch Getting Started tutorial on Spring.io. Here is the configuration file of the first job, the second being configured in the same way.

@Configuration
@EnableBatchProcessing
@Import({StandaloneInfrastructureConfiguration.class, ServicesConfiguration.class})
public class AddPodcastJobConfiguration {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    //reader, writer, processor...

}

To enable modularization I created an AppConfig class, where I define factories for the two jobs:

@Configuration
@EnableBatchProcessing(modular=true)
public class AppConfig {

    @Bean
    public ApplicationContextFactory addNewPodcastJobs(){
        return new GenericApplicationContextFactory(AddPodcastJobConfiguration.class);
    }

    @Bean
    public ApplicationContextFactory newEpisodesNotificationJobs(){
        return new GenericApplicationContextFactory(NotifySubscribersJobConfiguration.class);
    }    

}

P.S. I am new to Spring configuration in Java configuration Spring Boot and Spring Batch...


回答1:


Just set the "spring.batch.job.names=myJob" property. You could set it as SystemProperty when you launch your application (-Dspring.batch.job.names=myjob). If you have defined this property, spring-batch-starter will only launch the jobs, that are defined by this property.




回答2:


To run the jobs you like from the main method you can load the the required job configuration bean and the JobLauncher from the application context and then run it:

@ComponentScan
@EnableAutoConfiguration
public class ApplicationWithJobLauncher {

    public static void main(String[] args) throws BeansException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException, InterruptedException {

        Log log = LogFactory.getLog(ApplicationWithJobLauncher.class);

        SpringApplication app = new SpringApplication(ApplicationWithJobLauncher.class);
        app.setWebEnvironment(false);
        ConfigurableApplicationContext ctx= app.run(args);
        JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
        JobParameters jobParameters = new JobParametersBuilder()
            .addDate("date", new Date())
            .toJobParameters();  

        if("1".equals(args[0])){
            //addNewPodcastJob
            Job addNewPodcastJob = ctx.getBean("addNewPodcastJob", Job.class);          
            JobExecution jobExecution = jobLauncher.run(addNewPodcastJob, jobParameters);                   
        } else {
            jobLauncher.run(ctx.getBean("newEpisodesNotificationJob",  Job.class), jobParameters);   

        } 

        System.exit(0);
    }
}

What was causing my lots of confusion was that the second job were executed, even though the first job seemed to be "picked up" by the runner... Well the problem was that in both job's configuration file I used standard method names writer(), reader(), processor() and step() and it used the ones from the second job that seemed to "overwrite" the ones from the first job without any warnings... I used though an application config class with @EnableBatchProcessing(modular=true), that I thought would be used magically by Spring Boot :

@Configuration
@EnableBatchProcessing(modular=true)
public class AppConfig {

    @Bean
    public ApplicationContextFactory addNewPodcastJobs(){
        return new GenericApplicationContextFactory(AddPodcastJobConfiguration.class);
    }

    @Bean
    public ApplicationContextFactory newEpisodesNotificationJobs(){
        return new GenericApplicationContextFactory(NotifySubscribersJobConfiguration.class);
    }    

}

I will write a blog post about it when it is ready, but until then the code is available at https://github.com/podcastpedia/podcastpedia-batch (work/learning in progress)..




回答3:


There is the CommandLineJobRunner and maybe can be helpful.
From its javadoc

Basic launcher for starting jobs from the command line



来源:https://stackoverflow.com/questions/25122103/how-to-select-which-spring-batch-job-to-run-based-on-application-argument-spri

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!