好,直接进入主题
- maven依赖
<!-- 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); } } } }
请注意:List<SysBatch> list 这个获取到的是数据库中的记录封装成的实体,表结构如下
获取到的记录通过QuartJobUtil工具类的方法加载到定时中
管理定时工具类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);
BatchJobCall.class类是定时触发的响应类,CommonConstants.JOB_DATA_KEY 是一个常量,目的是在响应类中获取到sysBatch实体。
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 {
//获取实体
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();
}
}
`
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。