Spring boot quartz example

Gradle build file to Resolve JAR Dependency

Build.gradle config  dependencies:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
        mavenCentral()
    }
}


apply plugin: 'java'

plugins { id "io.spring.dependency-management" version "1.0.4.RELEASE" }

jar {
    baseName = 'spring-redis'
    version = '0.0.1-SNAPSHOT'
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-redis")
    compile group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '2.25.1'
    compile 'org.springframework.data:spring-data-commons:1.9.1.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-security:1.2.0.RELEASE'
    compile group: 'org.quartz-scheduler', name: 'quartz', version: '2.2.3'
}

- Configuration BatchApplication:

Trong class BatchApplication:

@SpringBootApplication
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class, args);
    }
}

- Configuration QuartzConfig


@Configuration
@Import(CaculatePoints.class)
public class QuartzConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzConfig.class);

    @Value("${org.quartz.scheduler.instanceName}")
    private String instanceName;

    @Value("${org.quartz.scheduler.instanceId}")
    private String instanceId;

    @Value("${org.quartz.threadPool.threadCount}")
    private String threadCount;

    @Autowired
    @Qualifier("cronCaculatePointsTriggerBean")
    private CronTriggerFactoryBean cronCaculatePointsTrigger;

    @Bean
    public org.quartz.spi.JobFactory jobFactory(ApplicationContext applicationContext) {
        QuartzJobFactory JobFactory = new QuartzJobFactory();
        JobFactory.setApplicationContext(applicationContext);
        return JobFactory;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(ApplicationContext applicationContext) {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();

        factory.setOverwriteExistingJobs(true);
        factory.setJobFactory(jobFactory(applicationContext));

        Properties quartzProperties = new Properties();
        quartzProperties.setProperty("org.quartz.scheduler.instanceName", instanceName);
        quartzProperties.setProperty("org.quartz.scheduler.instanceId", instanceId);
        quartzProperties.setProperty("org.quartz.threadPool.threadCount", threadCount);

        factory.setQuartzProperties(quartzProperties);
        factory.setTriggers(cronCaculatePointsTrigger.getObject());
        LOGGER.info("starting jobs...");

        return factory;
    }
}

In this QuartzConfig.class we will trigger a cronJob with Job as cronCaculatePointsTrigger.

- Configuration QuartzJobFactory

public class QuartzJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzJobFactory.class);

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        beanFactory = applicationContext.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        LOGGER.info("create job instance");
        beanFactory.autowireBean(job);
        return job;
    }
}

- createService "CaculatePointsService"

@Service
public class CaculatePointsService {

	private static final Logger LOGGER = LoggerFactory.getLogger(CaculatePointsService.class);

	public void caculatePoints() {
		LOGGER.info("TODO SOMETHINGS");
	}
}

This service simply logs out the console with "TODO SOMETHINGS"!

- createJob "CaculatePointsJob"

public class CaculatePointsJob implements Job {

    @Autowired
    private CaculatePointsService cronService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        cronService.caculatePoints();
    }

}
  • - Configuration shedule

@Configuration
public class CaculatePoints {

    @Value("${job.startDelay}")
    private Long startDelay;

    @Value("${job.repeatInterval}")
    private Long repeatInterval;

    @Value("${job.description}")
    private String description;

    @Value("${job.key}")
    private String key;


    @Bean(name = "caculatePointsTriggerBean")
    public SimpleTriggerFactoryBean caculatePointsTriggerBean() {
        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
        factoryBean.setJobDetail(caculateJobDetails().getObject());
        factoryBean.setStartDelay(startDelay);
        factoryBean.setRepeatInterval(repeatInterval);
        factoryBean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
        factoryBean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
        return factoryBean;
    }

    @Bean(name = "cronCaculatePointsTriggerBean")
    public CronTriggerFactoryBean cronCaculatePointsTriggerBean() {
        CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();
        stFactory.setJobDetail(caculateJobDetails().getObject());
        stFactory.setStartDelay(startDelay);
        stFactory.setCronExpression("* * * ? * *");
        return stFactory;
    }

    @Bean(name = "caculateJobDetails")
    public JobDetailFactoryBean caculateJobDetails() {
        JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(CaculatePointsJob.class);
        jobDetailFactoryBean.setDescription(description);
        jobDetailFactoryBean.setDurability(true);
        jobDetailFactoryBean.setName(key);

        return jobDetailFactoryBean;
    }

}

In this schedule file I created a cronJob called cronCaculatePointsTriggerBean, which calls CronTriggerFactoryBean a JobDetailFactoryBean and starts with every second via expression: * * *? * *,.

and parameters such as

 @Value("${job.startDelay}")
    private Long startDelay;

    @Value("${job.repeatInterval}")
    private Long repeatInterval;

    @Value("${job.description}")
    private String description;

    @Value("${job.key}")
    private String key;

will be fixed in the application.yml file as follows:

org:
  quartz:
    scheduler:
      instanceName: caculatePoints
      instanceId: AUTO
    threadPool:
      threadCount: 5
job:
  startDelay: 0
  repeatInterval: 60000
  description: caculatePoints batch
  key: StatisticsJob

Useful Resources:

 

Spring boot quartz 

 

Spring boot official