简体   繁体   中英

scheduling more than one batch job in spring boot application

My spring boot batch application has a scheduler which schedules my batch job written in FirstBatchConfiguration class to run every hour.

I have another batch job which I have configured in SecondBatchConfiguration class in the same application which i will be scheduling to run once in a week, but I am not able to figure out how to schedule it in the same JobScheduler so that both jobs should run at their own scheduled times.

If someone could help me to achieve this.

My current scheduler is:

@Component
public class JobScheduler {

    @Autowired
    private JobLauncher jobLauncher;

    @Autowired
    private FirstBatchConfiguration firstBatchConfiguration;

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void runJob() {

        Map<String, JobParameter> confMap = new HashMap<>();
        confMap.put("time", new JobParameter(System.currentTimeMillis()));
        JobParameters jobParameters = new JobParameters(confMap);
        final Logger logger = LoggerFactory.getLogger("applicationlogger");

        try {

            jobLauncher.run(firstBatchConfiguration.firstJob(), jobParameters);

        } catch (JobExecutionAlreadyRunningException | JobInstanceAlreadyCompleteException
                | JobParametersInvalidException | org.springframework.batch.core.repository.JobRestartException e) {

            logger.error(e.getMessage());
        }
    }

}

If the program have to run a second schedule then add a new method with Schedule annotation for example @Scheduled(cron = "5 8 * * 6?") . If you need to use the SecondBatchConfiguration class then just Autowired it.

  1. Step1 (autowired your configuration) @Autowired your SecondBatchConfiguration

Example:

@Autowired
private SecondBatchConfiguration secondBatchConfiguration;
  1. Create a new method and schedule it with @Scheduled annotation, and in the method body launch the second job.

Example:

@Scheduled(cron = "5 8 * * 6 ?")
public void runSecondJob() { ... }

You can have multiple schedules as many as you need, and every one with its own schedule.

@Scheduled(cron = "5 8 * * 6 ?")
public void runSecondJob() { .... }

@Scheduled(cron = "0 0 0/1 * * ?")
public void runJob() { .... }

EDIT: Asynchronous Job Execution

Async job excecution is a very powerful feature of spring batch, there is a good documentation and examples about it.

Please see the following instructions in order to activate async job exception:

Step 1: Add Job Configuration (this alternative is using In-Memory JobRepository). To read more about repository types go to Spring Documentation

Create a ResourcelessTransactionManager Bean

   @Bean
    public ResourcelessTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

Create MapJobRepositoryFactory Bean

@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
        ResourcelessTransactionManager txManager) throws Exception {
    MapJobRepositoryFactoryBean factory = new
            MapJobRepositoryFactoryBean(txManager);
    factory.afterPropertiesSet();
    return factory;
}

Create JobRepository Bean

@Bean
public JobRepository jobRepository(
        MapJobRepositoryFactoryBean factory) throws Exception {
    return factory.getObject();
}

Create a ThreadPoolExecutor (ThreadPoolExecutor is responsible for Async execution, there are more types of executors and you can read more about them in Spring Documentation )

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    taskExecutor.setCorePoolSize(5);
    taskExecutor.setMaxPoolSize(10);
    taskExecutor.setQueueCapacity(30);
    return taskExecutor;
}

Create a JobLauncher bean

   @Bean
    public JobLauncher jobLauncher(ThreadPoolTaskExecutor taskExecutor, JobRepository jobRepository){
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setTaskExecutor(taskExecutor);
        jobLauncher.setJobRepository(jobRepository);
        return jobLauncher;
    }

Step 2: Enable Async Job Execution

Go to you Spring Boot Application Class and the following Annotations

@EnableBatchProcessing
@EnableAsync
@EnableScheduling
@SpringBootApplication
public class MyBatchApp {

By default, Spring Boot will use just a single thread for all scheduled tasks to run. These tasks will be blocking. Instead, I would configure the scheduler to run each scheduled task in a separate thread:

@Configuration
public class SchedulerConfig implements SchedulingConfigurer
{    private final int POOL_SIZE = 10;
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar)
    {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();

        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("scheduled-task-pool-");
        threadPoolTaskScheduler.initialize();

        taskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM