Spring 3整合Quartz 2实现定时任务:动态添加任务

先展示一下后台管理定时任务效果图:

1、新增任务页面:

 

2、列表页(实现任务的禁用启用)

3、数据库脚本:

-- ----------------------------
-- Table structure for schedule_job
-- ----------------------------
DROP TABLE IF EXISTS `schedule_job`;
CREATE TABLE `schedule_job` (
`jobid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
`jobname` varchar(40) DEFAULT NULL COMMENT '任务名称',
`jobgroup` varchar(40) DEFAULT NULL COMMENT '任务分组',
`jobstatus` char(1) NOT NULL DEFAULT '1' COMMENT '任务状态 0禁用 1启用',
`auditstatus` char(1) NOT NULL DEFAULT '0' COMMENT '审核状态 0 已创建 1 审核通过 2 审核驳回',
`cronexpression` varchar(40) NOT NULL COMMENT '任务运行时间表达式',
`quartzclass` varchar(255) DEFAULT NULL COMMENT '定时任务处理类',
`description` varchar(280) DEFAULT NULL COMMENT '描述信息',
PRIMARY KEY (`jobid`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;

4、定时任务后台处理类(核心):

package com.eb.admin.schedule;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import com.eb.admin.entity.ScheduleJob;
import com.eb.admin.service.ConfigService;

/**
* 调度工厂类
*
* @author Jason.Yan
* @since 2018/03/28
*
*/
@Configuration
@EnableScheduling
@Component
public class ScheduleFactory {

private static Logger logger = LoggerFactory.getLogger(ScheduleFactory.class);

private Map<String, String> jobUniqueMap = new HashMap<String, String>(); // 当前Trigger使用的

@Autowired
private SchedulerFactoryBean schedulerFactoryBean;

public SchedulerFactoryBean getSchedulerFactoryBean() {
return schedulerFactoryBean;
}

public void setSchedulerFactoryBean(SchedulerFactoryBean schedulerFactoryBean) {
this.schedulerFactoryBean = schedulerFactoryBean;
}

@Autowired
private ConfigService configService;

public ConfigService getConfigService() {
return configService;
}

public void setConfigService(ConfigService configService) {
this.configService = configService;
}

//TODO 此处暂且注释,后续有后台定时任务逻辑 开启
@Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务
public void scheduleUpdateCronTrigger() throws Exception {

try {
// schedulerFactoryBean 由spring创建注入
Scheduler scheduler = schedulerFactoryBean.getScheduler();
List<ScheduleJob> jobList = configService.findLegalJobList();

// 获取最新删除(禁用)任务列表,将其从调度器中删除,并且从jobUniqueMap中删除
List<ScheduleJob> jobDelList = configService.findDelJobList();
for (ScheduleJob delJob : jobDelList) {
JobKey jobKey = JobKey.jobKey(delJob.getJobName(), delJob.getJobGroup());
scheduler.deleteJob(jobKey);
jobUniqueMap.remove(TriggerKey.triggerKey(delJob.getJobName(), delJob.getJobGroup()));
}

for (ScheduleJob job : jobList) {

TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
// 获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

String dbCron = job.getCronExpression(); // 该job数据库中的Trigger表达式
// 不存在,创建一个
if (null == trigger) {
//JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
try{
@SuppressWarnings("unchecked")
Class <? extends Job> clazz = (Class<? extends Job>) Class.forName(job.getQuartzClass());
JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", job);
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
// 按新的cronExpression表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();

jobUniqueMap.put(triggerKey.toString(), trigger.getCronExpression());
//currentCron = trigger.getCronExpression();

scheduler.scheduleJob(jobDetail, trigger);
}catch(Exception e){
e.printStackTrace();
logger.error(e.getMessage());
}

} else if(!jobUniqueMap.get(triggerKey.toString()).equals(dbCron)){
// Trigger已存在,那么更新相应的定时设置
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(dbCron);
// 按新的cronExpression表达式重新构建trigger

trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);

jobUniqueMap.put(triggerKey.toString(), dbCron);
}
}

} catch (Exception e) {
e.printStackTrace();
}
}
}

5、后台查询sql:

ConfigService.findLegalJobList=select * from schedule_job where jobstatus = 1 and auditstatus = 1

ConfigService.findDelJobList=select * from schedule_job where jobstatus = 0

6、后台查询方法实现类:

package com.eb.admin.service.impl;

import java.util.List;

import com.eb.admin.entity.ScheduleJob;
import com.eb.admin.service.ConfigService;
import com.eb.dataservice.dao.CommonDao;
import com.eb.dataservice.dao.SqlUtils;

public class ConfigServiceImpl implements ConfigService {

@SuppressWarnings("unchecked")
@Override
public List<ScheduleJob> findLegalJobList() throws Exception {
CommonDao dao = CommonDao.getDao(dbkey);
String sql = SqlUtils.getSql("ConfigService.findLegalJobList");
return dao.findBeanList(ScheduleJob.class, sql);
}

@Override
public List<ScheduleJob> findDelJobList() throws Exception {
CommonDao dao = CommonDao.getDao(dbkey);
String sql = SqlUtils.getSql("ConfigService.findDelJobList");
return dao.findBeanList(ScheduleJob.class, sql);
}

}

以上为本人根据两篇博文所做的整理修改,原文参见:

https://blog.csdn.net/liuchuanhong1/article/details/60873295#reply

https://www.ktanx.com/blog/p/308

本着尊重原作者的态度,转载请注明出处:

http://www.cnblogs.com/Ivan-j2ee/p/8697054.html

原文地址:https://www.cnblogs.com/Ivan-j2ee/p/8697054.html