这里用的是QuartzManager和ScheduleJobInitListener实现的可实时更新的动态定时任务。(修改配置值时实时更新)
使用ScheduleJobInitListener来实现实时更新,使用QuartzManager来实现动态维护。ps:(动态维护的本质是更改trigger )
下面开始介绍内容:
首先项目启动时进入监听器初始化定时任务。
//首先项目启动时进入监听器初始化定时任务。
@Component
@Order(value = 1)
public class ScheduleJobInitListener implements CommandLineRunner {
@Autowired
JobService scheduleJobService;
@Autowired
QuartzManager quartzManager;
@Override
public void run(String... arg0) throws Exception {
try {
scheduleJobService.initSchedule();
} catch (Exception e) {
e.printStackTrace();
}
}
}
然后来看scheduleJobService.initSchedule()方法
这里进数据库获取所有状态可用的任务。然后用quartzManager.addJob()方法添加。
@Override
public void initSchedule() throws SchedulerException {
// 这里获取任务信息数据
List<TaskDO> jobList = taskScheduleJobMapper.list(new HashMap<String, Object>(16));
for (TaskDO scheduleJob : jobList) {
if ("1".equals(scheduleJob.getJobStatus())) {
ScheduleJob job = ScheduleJobUtils.entityToData(scheduleJob);
quartzManager.addJob(job);
}
}
}
然后来看quartzManager.addJob(job)方法
这里的addJob是针对于任务调度的维护。
刚才的JobService是真对于数据库数据的任务表维护。
这里的scheduler 对象 是由@Autowired private Scheduler scheduler;注入,org.quartz包下提供的类。
* 添加任务
*
* @param scheduleJob
* @throws SchedulerException
*/
public void addJob(ScheduleJob job) {
try {
// 创建jobDetail实例,绑定Job实现类
// 指明job的名称,所在组的名称,以及绑定job类
Class<? extends Job> jobClass = (Class<? extends Job>) (Class.forName(job.getBeanClass()).newInstance()
.getClass());
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(job.getJobName(), job.getJobGroup())// 任务名称和组构成任务key
.build();
// 定义调度触发规则
// 使用cornTrigger规则
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())// 触发器key
.startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression())).startNow().build();
// 把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
以上是Scheduler 定时任务 初始化的过程。
现在我们来看看 动态维护的过程。
首先页面点击后进Controller,在此进数据库更改状态,
@PostMapping(value = "/changeJobStatus")
@ResponseBody
public R changeJobStatus(Long id,String cmd ) {
if (Constant.DEMO_ACCOUNT.equals(getUsername())) {
return R.error(1, "演示系统不允许修改,完整体验请部署程序");
}
String label = "停止";
if ("start".equals(cmd)) {
label = "启动";
} else {
label = "停止";
}
try {
taskScheduleJobService.changeStatus(id, cmd);
return R.ok("任务" + label + "成功");
} catch (Exception e) {
e.printStackTrace();
}
return R.ok("任务" + label + "失败");
}
service实现:判断此任务状态,终止则删除;开启则添加
@Override
public void changeStatus(Long jobId, String cmd) throws SchedulerException {
TaskDO scheduleJob = get(jobId);
if (scheduleJob == null) {
return;
}
//判断此任务状态
if (Constant.STATUS_RUNNING_STOP.equals(cmd)) {
//终止则删除
quartzManager.deleteJob(ScheduleJobUtils.entityToData(scheduleJob));
scheduleJob.setJobStatus(ScheduleJob.STATUS_NOT_RUNNING);
} else {
if (!Constant.STATUS_RUNNING_START.equals(cmd)) {
} else {
scheduleJob.setJobStatus(ScheduleJob.STATUS_RUNNING);
quartzManager.addJob(ScheduleJobUtils.entityToData(scheduleJob));
}
}
update(scheduleJob);
}
ps:看一下quartzManager.deleteJob细节:在此还是通过org.quartz.scheduler对象提供的方法删掉。
/**
* 删除一个job
* 在此还是通过org.quartz.scheduler对象提供的方法删掉
* @param scheduleJob
* @throws SchedulerException
*/
public void deleteJob(ScheduleJob scheduleJob) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
scheduler.deleteJob(jobKey);
}