1 前言
之前使用 quartz 进行过简单实验,体验过 quartz 进行最基本的调度,接下来深入研究更改时间调度和删除调度。目的是为了体验 quartz 的更新及删除操作,所以不做层次分离,所有方法都放在 controller 层来写,然后使用 swagger 进行测试(没有配置 swagger, 就直接在浏览器中输入链接也可以)。
2 添加依赖
在 springboot 项目中的 pom.xml 文件中添加 quartz 依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.1</version>
</dependency>
3 创建调度
编写job, 在项目中创建 job 目录, 在 job 目录下创建 HelloJob.java 类(名字可以随便起),类的内容为:
package com.fcy.demo.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
System.out.println("hello " + name);
}
}
在 controller 中添加创建调度的方法:
@RequestMapping(value = "/quartz", method = RequestMethod.GET)
public void work(String name, String cron) throws Exception {
//定时器对象
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//定义一个工作对象 设置工作名称与组名
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1","group1").build();
job.getJobDataMap().put("name", name);
//定义一个触发器 简单Trigger 设置工作名称与组名 5秒触发一次
// Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").startNow().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(5)).build();
//定义一个任务调度的Trigger 设置工作名称与组名 每天的24:00触发一次
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").withSchedule(CronScheduleBuilder.cronSchedule(cron)).build();
//设置工作 与触发器
scheduler.scheduleJob(job, trigger);
// and start it off
//开始定时任务
scheduler.start();
}
可以看到有两个参数,第一个为要在调度中放入的参数,也即在 job 中需要打印到控制台的变量,第二个为调度时间的表达式。
完成后启动项目进行测试,输入正确参数,如 name =“world”, cron="*/2 * * * * ?",即可发现控制台每隔两秒输出 hello world。证明创建调度成功。
4 删除调度
在同一个(不同也行) controller 中添加删除调度的方法:
@RequestMapping(value = "/deleteQuartz", method = RequestMethod.GET)
public void removeJob(String jobName, String jobGroup, String triggerName, String triggerGroup){
try {
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
Scheduler sched = sf.getScheduler();
sched.pauseTrigger(triggerKey);
sched.unscheduleJob(triggerKey);
sched.deleteJob(jobKey);
}catch (Exception e){
e.printStackTrace();
}
}
完成之后启动项目进行测试,可以先调用创建调度的方法创建一个调度,然后再测试改方法,发现控制台输出停止即为该方法成功。
5 更新调度
在 controller 中添加更新调度的方法:
@RequestMapping(value = "/updateQuartz", method = RequestMethod.GET)
public void modifyJobTime(String triggerName, String triggerGroup, String cron, String name) throws SchedulerException{
Scheduler sched = sf.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
try {
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null){
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)){
// 第一种方法,只修改调度时间
// TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// triggerBuilder.withIdentity(triggerKey);
// triggerBuilder.startNow();
// triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// trigger = (CronTrigger) triggerBuilder.build();
// sched.rescheduleJob(triggerKey, trigger);
//第二种方法,允许修改jobDataMap 中的数据
removeJob("job1", "group1", triggerName, triggerGroup);
work(name, cron);
}
}catch (Exception e){
e.printStackTrace();
}
}
更新调度的方法有两种,第一种方法是只更新调度时间,而第二种方法可以更新调度时间和可以放到 job 里面的参数,可以分别进行测试。现举例第二种,先调用创建调度的方法创建一个调度,如 name=world, cron="/2 * * * * ?", 即每两秒输出一次 hello world, 然后调用该方法,如:triggerName=trigger1, triggerGroup=group1, cron="/5 * * * * ?", name=Tim, 输入完参数后调用会发现控制台的输出从每两秒钟输出一次 hello world 变成每 5 秒输出一次 hello Tim. 证明更新调度成功。更新成功后仍可以调用删除调度将调度停止及删除。
6 其他
只是为了体验更新及删除调度,并没有做业务处理,在真实项目中,可能会根据项目要求做业务处理,此时有的参数就可以封装到方法中或者在 service 中做处理,都是可以的,具体问题具体分析。