【问题标题】:how to select which spring batch job to run based on application argument - spring boot java config如何根据应用程序参数选择要运行的spring批处理作业-spring boot java config
【发布时间】:2014-09-27 03:05:33
【问题描述】:

我在同一个项目中有两个独立的 spring 批处理作业,因为我想使用相同的基础设施相关 bean。一切都是用 Java 配置的。我想知道是否有一种正确的方法可以独立地启动作业,例如基于 main 方法中的第一个 java app 参数。如果我运行SpringApplication.run,则只有第二个作业会被魔法执行。 主要方法如下:

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

}

这两个作业的配置如 Spring.io 上的 Spring Batch 入门教程中所述。这是第一个作业的配置文件,第二个以相同的方式配置。

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

    @Autowired
    private JobBuilderFactory jobs;

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

}

为了实现模块化,我创建了一个 AppConfig 类,我在其中定义了两个作业的工厂:

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

}

附:我是 Java 配置 Spring Boot 和 Spring Batch 中的 Spring 配置新手...

【问题讨论】:

  • 这不是 Spring Boot 应用程序。如果您有一些适用于 Spring Boot 的东西,为什么需要帮助?
  • 抱歉 Dave 我的愚蠢问题,但我是 Spring Boot、Spring Batch 和 Java 配置的新手。我想要实现的是在同一个代码库中拥有两个以上的作业,以便它们可以共享 JPA 实体,例如...,但仍然可以使用 Spring Boot 以某种方式分别运行它们。

标签: spring spring-batch spring-boot spring-java-config


【解决方案1】:

只需设置“spring.batch.job.names=myJob”属性。您可以在启动应用程序时将其设置为 SystemProperty (-Dspring.batch.job.names=myjob)。如果您已定义此属性,则 spring-batch-starter 将仅启动由此属性定义的作业。

【讨论】:

  • 这是将 Spring-batch 与 Spring-boot 一起使用时的正确答案。当然它假定BatchAutoConfiguration 没有被禁用(它创建一个JobLauncherCommandLineRunner 并将作业名称传递给它)。
【解决方案2】:

要从 main 方法运行您喜欢的作业,您可以从应用程序上下文加载所需的作业配置 bean 和 JobLauncher,然后运行它:

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

引起我很多困惑的是第二个工作被执行了,即使第一个工作似乎被跑步者“捡起”......问题是在两个工作的配置文件中我都使用了标准方法名称writer(), reader(), processor() and step() 并且它使用了第二份工作中的那些似乎“覆盖”了第一份工作中的那些而没有任何警告...... 我使用了带有@EnableBatchProcessing(modular=true) 的应用程序配置类,我认为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);
    }    

}

当它准备好后,我会写一篇关于它的博客文章,但在那之前,代码可以在https://github.com/podcastpedia/podcastpedia-batch 获得(工作/学习中)..

【讨论】:

【解决方案3】:

CommandLineJobRunner 可能会有所帮助。
从它的javadoc

用于从命令行启动作业的基本启动器

【讨论】:

  • 谢谢 Luca,但我在 CommandLineJobRunner 上也没有成功...
【解决方案4】:

通过在上下文中的某处添加 @EnableBatchProcessing(来自 Spring Batch)来启用 Spring Batch 自动配置。默认情况下,它在启动时执行应用程序上下文中的所有作业(有关详细信息,请参阅 JobLauncherCommandLineRunner)。您可以通过指定 spring.batch.job.names(逗号分隔的作业名称模式)来缩小到一个或多个特定作业。

-- Spring Boot Doc

或者禁用自动执行并使用 JobLauncher 根据传递给 main 方法的参数以编程方式从上下文运行作业

【讨论】:

    猜你喜欢
    • 2019-11-14
    • 2014-06-20
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    相关资源
    最近更新 更多