<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> </dependency>
配置
首先重写一下 QuartJob工厂,解决注入问题
public class QuartJobFactory extends AdaptableJobFactory { @Autowired private AutowireCapableBeanFactory capableBeanFactory; @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // 调用父类的方法 Object jobInstance = super.createJobInstance(bundle); // Spring注入 capableBeanFactory.autowireBean(jobInstance); return jobInstance; } }
重写 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); } } } }
管理定时工具类QuartJobUtil
`
public class QuartJobUtil { private static final Log log = LogFactory.getLog(QuartJobUtil.class); /** * 追加定时 * * @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)); //获取trigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); String cronExpression = sysBatch.getCron(); DateTime runTime = new DateTime(); runTime = runTime.plusMinutes(1); //不存在,创建一个 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(); //按新的cronExpression表达式构建一个新的trigger trigger = triggerFactory.getObject(); log.debug("增加批处理: "); 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 { // 已存在,那么更新相应的设置 jobDetail.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch); CronTriggerFactoryBean triggerFactory = new CronTriggerFactoryBean(); // 将最新的 Batch 添加到 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(); //按新的cronExpression表达式构建一个新的trigger trigger = triggerFactory.getObject(); log.debug("修改批处理: "); log.debug(jobName + "-" + jobGroup); log.debug(sysBatch.getName()); log.debug(cronExpression); } catch (ParseException e) { log.warn(e); } //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } /** * 删除批处理 * * @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("删除批处理:" + jobName); log.info("删除结果:" + result); } }
`
这里面最重要的是
jobDetailFactory.setJobClass(BatchJobCall.class);
jobDetail.getJobDataMap().put(CommonConstants.JOB_DATA_KEY, sysBatch);
`
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 { //获取实体 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() + "-定时任务开始执行具体方法:" + sdf.format(new Date())); Class<?> printClass = Class.forName(beanName); Object obj = printClass.newInstance(); capableBeanFactory.autowireBean(obj); //获取方法 Method printMethod = printClass.getMethod(beanMethod, String.class); //调用 printMethod.invoke(obj, argument); log.debug(batch.getBatchId() + "_" + batch.getName() + "-定时任务执行结束:" + sdf.format(new Date())); } catch (Exception e) { log.warn(batch.getBatchId() + "_" + batch.getName() + "-定时任务调用失败" + sdf.format(new Date())); throw new JobExecutionException(e); } } } }
`
在这里通过 反射机制 去调用表中sysbatch实体存的 类名以及方法名
最后配置QuartzConfig
`
@Configuration public class QuartzConfig { @Bean public QuartJobSchedulingListener quartJobSchedulingListener() { return new QuartJobSchedulingListener(); } /** * 获取定时任务工厂 * * @return 获取定时任务工厂 */ @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean(); schedulerFactory.setJobFactory(jobFactory()); return schedulerFactory; } /** * QuartJob工厂,解决注入问题 * * @return QuartJob工厂 */ @Bean public JobFactory jobFactory() { QuartJobFactory factory = new QuartJobFactory(); return factory; } /** * 调度 * * @return BatchJobCall */ @Bean public BatchJobCall getJobCall() { return new BatchJobCall(); } }
`