web-dev-qa-db-ja.com

アプリケーションの引数に基づいて実行するSpringBatchジョブを選択する方法-springboot Java config

同じインフラストラクチャ関連のBeanを使用したいので、同じプロジェクトに2つの独立した春のバッチジョブがあります。すべてがJavaで構成されています。たとえば、mainメソッドの最初のJava app引数に基づいて、独立してジョブを開始する適切な方法があるかどうかを知りたいです。SpringApplication.runを実行した場合のみ2番目のジョブは魔法によって実行されます。メインメソッドは次のようになります。

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

}

2つのジョブは、Spring.ioのSpring Batch GettingStartedチュートリアルに示されているように構成されています。これが最初のジョブの構成ファイルで、2番目のジョブも同じように構成されています。

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

    @Autowired
    private JobBuilderFactory jobs;

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

}

モジュール化を有効にするために、AppConfigクラスを作成しました。ここで、2つのジョブのファクトリを定義します。

@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. Java構成SpringBootおよびSpringBatch ..のSpring構成は初めてです。

9
amacoder

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

私の多くの混乱を引き起こしたのは、最初のジョブがランナーによって「ピックアップ」されたように見えたにもかかわらず、2番目のジョブが実行されたということでした...まあ問題は、両方のジョブの構成ファイルで標準のメソッド名を使用したことでしたwriter(), reader(), processor() and step()そしてそれは警告なしに最初のジョブからのものを「上書き」したように見える2番目のジョブからのものを使用しました...私は@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 (作業中/学習中)でコードを入手できます。

11
amacoder

「spring.batch.job.names = myJob」プロパティを設定するだけです。アプリケーションの起動時にSystemPropertyとして設定できます(-Dspring.batch.job.names = myjob)。このプロパティを定義した場合、spring-batch-starterはこのプロパティで定義されたジョブのみを起動します。

15

CommandLineJobRunner があり、おそらく役立つ可能性があります。
javadocから

コマンドラインからジョブを開始するための基本的なランチャー

0