第一个类:PlanScheduler
继承Thread类,每隔15秒读一次数据与目前Quartz队列中的数据对比,进行更新或者删除工作。
public class PlanScheduler extends Thread {
protected static Logger logger = LoggerFactory.getLogger(PlanScheduler.class);
@Autowired
private ProgramService programService;
private List<Crontab> crontabList = new ArrayList<Crontab>();
private Map<Integer, Crontab> crontabMap = new HashMap<Integer, Crontab>();
public void init() {
this.start();
}
@Override
public void run() {
logger.info("Crontab start...");
//获取ebd_compute_crontab中所有计划
crontabList = programService.getCrontablist();
for(Crontab crontab : crontabList){
crontabMap.put(crontab.getPlanId(), crontab);
}
//依次将这些计划加入Quartz
for(Crontab crontab : crontabList){
QuartzManager.addPlan(String.valueOf(crontab.getJobId()), JobPlan.class, crontab.getCronExpression());
}
while (!interrupted()) {
try {
sleep(15000);
} catch (InterruptedException e) {
break;
}
//每隔15秒,重新获取一次ebd_compute_crontab中的数据
List<Crontab> crontabUpdateList = programService.getCrontablist();
//遍历新加载的数据
for(Crontab crontabUpdate : crontabUpdateList){
//如果初始加载的数据的planId与新加载的一样
if(crontabMap.containsKey(crontabUpdate.getPlanId())){
//判断两者的planVersion是否相同,若不同,删除初始加载数据
if (crontabUpdate.getPlanVersion() != crontabMap.get(crontabUpdate.getPlanId()).getPlanVersion()) {
crontabMap.remove(crontabUpdate.getPlanId());
QuartzManager.removePlan(String.valueOf(crontabUpdate.getJobId()));
}
}else {
//删除新加载数据中不包含初始数据的项
crontabMap.remove(crontabUpdate.getPlanId());
QuartzManager.removePlan(String.valueOf(crontabUpdate.getJobId()));
}
}
for(Crontab crontabUpdate : crontabUpdateList){
//添加planVersion改变的项和新增项
if(!crontabMap.containsKey(crontabUpdate.getPlanId())){
QuartzManager.addPlan(String.valueOf(crontabUpdate.getJobId()), JobPlan.class, crontabUpdate.getCronExpression());
}
crontabMap.put(crontabUpdate.getPlanId(), crontabUpdate);
}
}
}
public void close() {
this.interrupt();
}
}
第二个类:JobPlan
通过Quartz调度,具体执行的Job,本例中是调用jobService.execute(jobId)方法。
有一个点要注意的是,这里不是使用
@Autowired
private JobService jobService
而是使用
private JobService jobService = SpringApplicationContext.getBean(JobService.class);
这个问题在调试的时候遇到,研究了好一会才弄出来。
public class JobPlan implements Job {
protected static Logger logger = LoggerFactory.getLogger(PlanScheduler.class);
private JobService jobService = SpringApplicationContext.getBean(JobService.class);
public void execute(JobExecutionContext context) throws JobExecutionException {
logger.info("Plan Execute....");
JobDataMap dataMap = context.getJobDetail().getJobDataMap();
String jobName = dataMap.getString("jobName");
int jobId = Integer.parseInt(jobName);
jobService.execute(jobId);
}
}
第三个类:QuartzManager
是具体执行增加,修改,删除Job的类,是使用Quartz具体操作的类。
public class QuartzManager {
private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";
private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME";
/**
* @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
* @param jobName 任务名
* @param cls 任务
* @param time 时间设置,参考quartz说明文档
*/
public static void addPlan(String jobName, Class cls, String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类
jobDetail.getJobDataMap().put("jobName", jobName);
// 触发器
CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
trigger.setCronExpression(time);// 触发器时间设定
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
* @param jobName
* @param time
*/
public static void modifyPlanTime(String jobName, String time) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName,TRIGGER_GROUP_NAME);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(time)) {
JobDetail jobDetail = sched.getJobDetail(jobName,JOB_GROUP_NAME);
Class objJobClass = jobDetail.getJobClass();
removePlan(jobName);
addPlan(jobName, objJobClass, time);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
* @param jobName
*/
public static void removePlan(String jobName) {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:启动所有定时任务
*/
public static void startPlans() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*/
public static void shutdownPlans() {
try {
Scheduler sched = gSchedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}