spring framework integration quartz
@Scheduled
Spring context support has two annotations for Scheduled tasks under spring, @ enablescheduled and @ Scheduled, which are easy to use
1. Add enableschedule where spring can scan
@SpringBootApplication @MapperScan("com.hsm.quartztask.mapper") @EnableScheduling public class QuartzTaskApplication { public static void main(String[] args) { SpringApplication.run(QuartzTaskApplication.class, args); } }
2. Write a method, and add @ Scheduled on the method body
@Slf4j @Component public class ScheduledDemo { @Scheduled(cron = "*/5 * * * * ? ") void init() { log.info("spring Own simple scheduled tasks"); } }
The details of the Scheduled attribute can be found in the following source code
Spring integration quartz
There is no code in the spring boot starter quartz project source code, which can be seen in the pom file
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>
Here you can directly use the spring context support project in the spring source code. For details, you can see the files under the org.springframework.scheduling.quartz package of this project
spring uses a lot of factory patterns, and what we have to do is instantiate these bean s. The source code can mainly look at the following files:
- AdaptableJobFactory this method can add some extensions to JobDateail
- QuartzJobBean optimizes the Job of quartz, and puts the data in dataMap directly into the attributes of instance task
- Jobdetailfactorybean JobDetail factory, most of which are also JobDetail properties
- SimpleTriggerFactoryBean SimpleTrigger factory
- Crontrigger factorybean crontrigger factory
- SchedulerFactoryBean scheduler factory
The steps for spring to schedule a scheduled task are similar to those for quartz:
- Write task classes that can inherit jobs or quartzjobbeans (quartzjobbeans inherit jobs)
- Instantiate JobDetailFactoryBean and bind the task class to it
- Instantiate TriggerFactoryBean and bind JobDetail to it
- Instantiate the SchedulerFactoryBean and bind the trigger factorybean to it
1. pom file
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
2. Example chemical plant
/** * QuartzJobBean The difference with job is that QuartzJobBean puts the datamap data of job directly into the properties of instance object */ private String name; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { //TODO invoice query log.info("from dataMap Data obtained in:{}", this.getName()); }
@Bean("invoiceQueryJobDetail") @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public JobDetailFactoryBean jobDetailFactoryBean() { Map<String,Object> dataMap = new HashMap<>(); dataMap.put("name", "Invoice query"); JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean(); jobDetailFactoryBean.setName("Task name"); jobDetailFactoryBean.setGroup("Task force"); jobDetailFactoryBean.setJobClass(InvoiceQueryJobBean.class); jobDetailFactoryBean.setJobDataAsMap(dataMap); // Must be set to true, if false, the task will be deleted in the scheduler when there is no active trigger associated with it jobDetailFactoryBean.setDurability(true); return jobDetailFactoryBean; } @Autowired private JobDetailFactoryBean invoiceQueryJobDetail; @Bean("invoiceQueryTrigger") @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public CronTriggerFactoryBean cronTriggerFactoryBean() { CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean(); cronTriggerFactoryBean.setName("Trigger Name "); cronTriggerFactoryBean.setGroup("Trigger group name"); cronTriggerFactoryBean.setJobDetail(invoiceQueryJobDetail.getObject()); cronTriggerFactoryBean.setCronExpression("*/5 * * * * ?"); return cronTriggerFactoryBean; } @Autowired private QuartzJobFactory quartzJobFactory; @Autowired private CronTriggerFactoryBean invoiceQueryTrigger; @Bean public SchedulerFactoryBean scheduler(){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(quartzJobFactory); schedulerFactoryBean.setTriggers(invoiceQueryTrigger.getObject()); return schedulerFactoryBean; }
Factory specific properties can be used by yourself
3. Use Spring Autowire
In order to use only the bean s in the Spring container directly in the Job class, the AdaptableJobFactory factory factory is instantiated here
@Component public class QuartzJobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); //Here, the properties are injected directly, so you can use the bean s in spring in the job capableBeanFactory.autowireBean(jobInstance); return jobInstance; } } //Inject the above bean as an attribute of the SchedulerFactoryBean @Bean public SchedulerFactoryBean scheduler(){ SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(quartzJobFactory); schedulerFactoryBean.setTriggers(invoiceQueryTrigger.getObject()); return schedulerFactoryBean; }
4. Share a tool class
@Slf4j public final class QuartzUtils { private QuartzUtils() { } /** * @Author: huangsm on 2019/5/28 17:58 * @param: [cronExpression] 0 0/5 * * * ? * @return: boolean * @Description: Check whether cron expression is correct */ public static boolean checkCron(String cronExpression){ return CronExpression.isValidExpression(cronExpression); } /** * @Author: huangsm on 2019/5/28 18:46 * @param: [cronExpression] * @return: void * @Description: Print next execution time every five seconds */ public static void printExeTimeWith5Senconds(String cronExpression){ CronExpression cron ; Date now = new Date(); try { cron = new CronExpression(cronExpression); //Last execution time Date lastDate = now; while(true){ log.info("Execution time:{}", lastDate); lastDate = cron.getNextValidTimeAfter(lastDate); Thread.sleep(5000L); } } catch (ParseException e) { log.error("cron Expression parsing exception", e); }catch (Exception e){ log.error("Printing cron Expression execution time exception", e); } } }