How to trigger a scheduled Spring Batch Job?

后端 未结 4 1388
日久生厌
日久生厌 2021-02-06 00:51

I want to be able to start my job with a REST controller, then when the job is started, it should run on a scheduled basis, until i stop it again with REST.

So this is m

4条回答
  •  梦毁少年i
    2021-02-06 01:29

    In first you are defining the job:

    @Bean
    @Qualifier("fancyScheduledJob")
    public Job job() {
        return jobBuilderFactory.get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }
    

    In second you are initiating the execution of this job:

    @Autowired
    @Qualifier(value = "fancyScheduledJob")
    private Job job;
    
    @Autowired
    private JobLauncher jobLauncher;
    
    @Scheduled(cron = "0/5 * * * * ?")
    public void launch() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobInstanceAlreadyExistsException, NoSuchJobException {
    
        jobLauncher.run(job, JobParametersBuilder()
                .addLong("launchTime", System.currentTimeMillis())
                .toJobParameters())
    }
    

    Also note that the "launchTime" paramter is introduced: by default spring batch is preventing launching the job with same parameter values.

    While your schedule is quite tight - every 5 seconds you should be aware of concurrency. Or if you want to be assured that at each and every moment only 1 instance of the job is executed you can configure custom single threaded job launcher:

    @Bean(name = "fancyJobExecutorPool")
    public TaskExecutor singleThreadedJobExecutorPool() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(100500);
        executor.setThreadNamePrefix("fancy-job-batch-");
        return executor;
    }
    
    @Bean(name = "fancyJobLauncher")
    public JobLauncher singleThreadedJobLauncher(JobRepository jobRepository)
    {
        SimpleJobLauncher sjl = new SimpleJobLauncher();
        sjl.setJobRepository(jobRepository);
        sjl.setTaskExecutor(singleThreadedJobExecutorPool());
        return sjl;
    }
    

    And use this single threaded job launcher during launch time.

    @Autowired
    @Qualifier("fancyJobLauncher")
    private JobLauncher jobLauncher;
    

    With this your job instances will be executed one by one (but this doesn't limits parallel execution of steps inside of your job).

提交回复
热议问题