OK, go straight to the subject
- maven dependence
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency>
-
To configure
First, rewrite the QuartJob factory to solve the injection problempublic class QuartJobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // Call the method of the parent class Object jobInstance = super.createJobInstance(bundle); // Spring injection capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
Rewrite listener
public class QuartJobSchedulingListener implements ApplicationListener<ContextRefreshedEvent> { private static final Logger log = LoggerFactory.getLogger(QuartJobSchedulingListener.class); @Override public void onApplicationEvent(ContextRefreshedEvent event) { try { if (event.getApplicationContext().getParent() == null) { log.debug("onApplicationEvent"); ApplicationContext applicationContext = event.getApplicationContext(); addDbBatchs(applicationContext); //addDynamicJobs(applicationContext); } } catch (Exception e) { log.error("", e); } } private void addDbBatchs(ApplicationContext applicationContext) { SchedulerFactoryBean schedulerFactoryBean = applicationContext.getBean(SchedulerFactoryBean.class); BatchTaskService taskService = applicationContext.getBean(BatchTaskService.class); List<SysBatch> list = taskService.getAllBatch(); for (SysBatch batch : list) { try { QuartJobUtil.addScheduler(schedulerFactoryBean, batch); } catch (Exception e) { log.error("", e); } } } }
Please note: List < sysbatch > list this is the entity encapsulated by the records in the database. The table structure is as follows
The acquired records are loaded into the timing through the methods of the QuartJobUtil utility class.
Management timing tool class QuartJobUtil
`
public class QuartJobUtil { private static final Log log = LogFactory.getLog(QuartJobUtil.class); /** * Additional timing * * @param schedulerFactoryBean * @param sysBatch * @throws SchedulerException */ public static void addScheduler(SchedulerFactoryBean schedulerFactoryBean, SysBatch sysBatch) throws SchedulerException { if (schedulerFactoryBean == null) { return; } Scheduler scheduler = schedulerFactoryBean.getScheduler(); String jobName = sysBatch.getBatchId(); String jobGroup = QuartzCron.JOB_GROUP_DYNAMIC; TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup); JobDetail jobDetail = scheduler.getJobDetail(new JobKey(jobName, jobGroup)); //Get trigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); String cronExpression = sysBatch.getCron(); DateTime runTime = new DateTime(); runTime = runTime.plusMinutes(1); //No, create a if (null == jobDetail) { JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean(); jobDetailFactory.setName(jobName); jobDetailFactory.setGroup(jobGroup); jobDetailFactory.setJobClass(BatchJobCall.class); jobDetailFactory.setDurability(true); jobDetailFactory.afterPropertiesSet(); jobDetail = jobDetailFactory.getObject(); jobDetail.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch); CronTriggerFactoryBean triggerFactory = new CronTriggerFactoryBean(); triggerFactory.setJobDetail(jobDetail); triggerFactory.setName(jobName); triggerFactory.setGroup(jobGroup); triggerFactory.setCronExpression(cronExpression); try { triggerFactory.afterPropertiesSet(); //Build a new trigger with a new cronExpression expression trigger = triggerFactory.getObject(); log.debug("Add batch: "); log.debug(jobName + "-" + jobGroup); log.debug(sysBatch.getName()); log.debug(cronExpression); } catch (ParseException e) { log.warn(sysBatch.getBatchId() + "_" + sysBatch.getCron(), e); } scheduler.scheduleJob(jobDetail, trigger); } else { // Existing, then update the corresponding settings jobDetail.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch); CronTriggerFactoryBean triggerFactory = new CronTriggerFactoryBean(); // Add the latest Batch to the Map triggerFactory.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch); triggerFactory.setJobDetail(jobDetail); triggerFactory.setName(jobName); triggerFactory.setGroup(jobGroup); triggerFactory.setCronExpression(cronExpression); //triggerFactory.setStartTime(runTime.toDate()); try { triggerFactory.afterPropertiesSet(); //Build a new trigger with a new cronExpression expression trigger = triggerFactory.getObject(); log.debug("Modify batch: "); log.debug(jobName + "-" + jobGroup); log.debug(sysBatch.getName()); log.debug(cronExpression); } catch (ParseException e) { log.warn(e); } //Reset job execution by new trigger scheduler.rescheduleJob(triggerKey, trigger); } } /** * Delete batch * * @param schedulerFactoryBean * @param sysBatch * @throws SchedulerException */ public static void deleteDocScheduler(SchedulerFactoryBean schedulerFactoryBean, SysBatch sysBatch) throws SchedulerException { if (schedulerFactoryBean == null) { return; } Scheduler scheduler = schedulerFactoryBean.getScheduler(); String jobName = sysBatch.getBatchId(); String jobGroup = QuartzCron.JOB_GROUP_DYNAMIC; JobKey jobKey = new JobKey(jobName, jobGroup); boolean result = scheduler.deleteJob(jobKey); log.info("Delete batch:" + jobName); log.info("Delete result:" + result); } }
`
The most important thing is
jobDetailFactory.setJobClass(BatchJobCall.class);
jobDetail.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch);
The BatchJobCall.class class class is a response class triggered at a fixed time. Commonconstants.job "data" key is a constant to obtain the sysBatch entity in the response class.
BatchJobCall
`
public class BatchJobCall extends QuartzJobBean { private static final Log log = LogFactory.getLog(BatchJobCall.class); @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { //Get entity SysBatch batch = (SysBatch) context.getJobDetail().getJobDataMap().get(CommonConstants.JOB_DATA_KEY); String beanName = batch.getBeanName(); String beanMethod = batch.getBeanMethod(); String argument = batch.getArgument(); if (StringUtils.isNotEmpty(beanName) && StringUtils.isNotEmpty(beanMethod)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS"); try { log.debug(batch.getBatchId() + "_" + batch.getName() + "-The specific method for starting the scheduled task is as follows:" + sdf.format(new Date())); Class<?> printClass = Class.forName(beanName); Object obj = printClass.newInstance(); capableBeanFactory.autowireBean(obj); //Acquisition method Method printMethod = printClass.getMethod(beanMethod, String.class); //call printMethod.invoke(obj, argument); log.debug(batch.getBatchId() + "_" + batch.getName() + "-End of scheduled task execution:" + sdf.format(new Date())); } catch (Exception e) { log.warn(batch.getBatchId() + "_" + batch.getName() + "-Timed task call failed" + sdf.format(new Date())); throw new JobExecutionException(e); } } } }
`
Here, the class name and method name of sysbatch entity in the table are called through the reflection mechanism.
Finally configure QuartzConfig
`
@Configuration public class QuartzConfig { @Bean public QuartJobSchedulingListener quartJobSchedulingListener() { return new QuartJobSchedulingListener(); } /** * Get scheduled task factory * * @return Get scheduled task factory */ @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean(); schedulerFactory.setJobFactory(jobFactory()); return schedulerFactory; } /** * QuartJob Factory, solve injection problem * * @return QuartJob factory */ @Bean public JobFactory jobFactory() { QuartJobFactory factory = new QuartJobFactory(); return factory; } /** * Dispatch * * @return BatchJobCall */ @Bean public BatchJobCall getJobCall() { return new BatchJobCall(); } }
`