在前两节的基础上做以下修改
1、新增任务实体类
/**
* 任务实体类
*
*/
public class Job {
private String name;
private String group;
private String cron;
private String desc;
private Integer status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
2、quartz工具类
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.study.config.TestJob;
import com.study.entity.Job;
@Component
public class QuartzUtil {
private static final Logger logger = LoggerFactory.getLogger(QuartzUtil.class);
@Autowired
private Scheduler scheduler;
/**
* 获取任务对应的key
* @param name
* @param group
* @return
*/
public JobKey getJobKey(String name, String group) {
return JobKey.jobKey(name, group);
}
/**
* 封装JobDataMap数据,在执行任务时可以调用
*
* @param job 自定义job实体类
* @return
*/
public JobDataMap getJobDataMap(Job job) {
JobDataMap map = new JobDataMap();
map.put("name", job.getName());
map.put("group", job.getGroup());
map.put("cron", job.getCron());
map.put("desc", job.getDesc());
map.put("status", job.getStatus());
return map;
}
/**
* 创建JobDetail
*
* @param jobKey 任务的唯一标识
* @param desc 任务的说明信息
* @param map 封装过需要在任务执行时使用的数据
* @param clazz 任务接口的实现的,复制执行对应业务
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public JobDetail getJobDetail(JobKey jobKey, String desc, JobDataMap map, Class clazz) {
return JobBuilder.newJob(clazz).withIdentity(jobKey).withDescription(desc).setJobData(map).storeDurably()
.build();
}
/**
* 创建任务触发器
*
* @param job
* @return
*/
public Trigger getTrigger(Job job) {
return TriggerBuilder.newTrigger().withIdentity(job.getName(), job.getGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCron())).build();
}
/**
* 暂停任务
*
* @param jobKey
*/
public boolean pauseJob(String name, String group) {
// 暂停任务
try {
logger.info("任务:{}暂停", name);
scheduler.pauseJob(this.getJobKey(name, group));
return true;
} catch (SchedulerException e) {
e.printStackTrace();
logger.info("任务:{}暂停失败", name);
return false;
}
}
/**
* 立即运行一次任务
*
* @param job
*/
public boolean runNow(Job job) {
// 立即调用一次任务
try {
logger.info("任务:{}开始运行", job.getName());
scheduler.triggerJob(this.getJobKey(job.getName(), job.getGroup()), this.getJobDataMap(job));
return true;
} catch (SchedulerException e) {
e.printStackTrace();
logger.info("任务:{}运行失败", job.getName());
return false;
}
}
/**
* 加人一个任务并且执行
*/
@SuppressWarnings("rawtypes")
public boolean joinJob(Job job, Class clazz) throws SchedulerException {
synchronized (logger) {
logger.info("任务:{}开始注入", job.getName());
// 获取正在执行的任务
//获取key
JobKey jobKey = this.getJobKey(job.getName(), job.getGroup());
scheduler.pauseJob(jobKey);
scheduler.unscheduleJob(TriggerKey.triggerKey(jobKey.getName(), jobKey.getGroup()));
scheduler.deleteJob(jobKey);
JobDataMap map = this.getJobDataMap(job);
JobDetail jobDetail = this.getJobDetail(jobKey, job.getDesc(), map, clazz);
// 若是任务状态支持注入
if (job.getStatus().equals(1)) {
scheduler.scheduleJob(jobDetail, this.getTrigger(job));
} else {
logger.info("任务:{}状态不支持注入", job.getName());
}
return true;
}
}
/**
* 初始化组人所有任务
*/
@PostConstruct
public void initialize() {
try {
logger.info("初始化注入所有任务");
reStartAllJobs();
} catch (SchedulerException e) {
logger.info("注入任务失败 : " + e.getMessage());
e.printStackTrace();
}
}
/**
* 重启所有任务
*/
public boolean refreshAll() {
try {
logger.info("正在重启所有任务");
reStartAllJobs();
return true;
} catch (SchedulerException e) {
logger.info("重启任务失败 : " + e.getMessage());
e.printStackTrace();
return false;
}
}
/**
* 注入数据库中所有任务
*
* @throws SchedulerException
*/
private void reStartAllJobs() throws SchedulerException {
// 只允许一个线程进入操作
synchronized (logger) {
// 获取正在执行的任务
Set<JobKey> set = scheduler.getJobKeys(GroupMatcher.anyGroup());
// 暂停所有JOB
scheduler.pauseJobs(GroupMatcher.anyGroup());
for (JobKey jobKey : set) {
// 删除从数据库中注册的所有JOB
scheduler.unscheduleJob(TriggerKey.triggerKey(jobKey.getName(), jobKey.getGroup()));
scheduler.deleteJob(jobKey);
}
// 从数据库中注册的所有JOB
List<Job> jobs = this.loadJobs();
if (jobs != null && jobs.size() > 0) {
for (Job job : jobs) {
logger.info("任务:{}开始注入", job.getName());
JobDataMap map = this.getJobDataMap(job);
JobKey jobKey = this.getJobKey(job.getName(), job.getGroup());
JobDetail jobDetail = this.getJobDetail(jobKey, job.getDesc(), map, TestJob.class);
// 若是任务状态支持注入
if (job.getStatus().equals(1)) {
scheduler.scheduleJob(jobDetail, this.getTrigger(job));
} else {
logger.info("任务:{}状态不支持注入", job.getName());
}
}
}
}
}
/**
* 模拟从数据去中获取所有任务
*
* @return
*/
public List<Job> loadJobs() {
List<Job> list = new ArrayList<Job>();
Job job = new Job();
job.setName("wuyu");
job.setGroup("wuyu");
job.setCron("0/5 * * * * ?");
job.setDesc("测试任务");
job.setStatus(1);
list.add(job);
return list;
}
}
3、新增两个任务实现
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class TestJob implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("任务执行了");
//获取任务创建时传递的数据信息
JobDataMap dataMap = context.getMergedJobDataMap();
System.out.println(dataMap.get("desc") + ":" + dataMap.get("name"));
}
}
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class TestJob1 implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("我是新任务,我正在执行。。。");
//获取任务创建时传递的数据信息
JobDataMap dataMap = context.getMergedJobDataMap();
System.out.println(dataMap.get("desc") + ":" + dataMap.get("name"));
}
}
4、controller层业务实现
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import com.study.config.TestJob;
import com.study.config.TestJob1;
import com.study.entity.Job;
import com.study.utils.QuartzUtil;
@RestController
public class TestQuartzController {
@Autowired
private QuartzUtil quartzUtil;
/**
* 加人任务并执行
* @return
*/
@GetMapping("/testJoin")
public String testJoin() {
System.out.println("测试加人任务并执行");
Job job = new Job();
job.setName("job1");
job.setGroup("group1");
job.setCron("0/5 * * * * ?");
job.setStatus(1);
job.setDesc("测试加人任务并执行");
try {
boolean b = quartzUtil.joinJob(job, TestJob1.class);
if(b) {
return "success";
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return "fail";
}
/**
* 暂停任务
* @return
*/
@GetMapping("/testPause")
public String testPause() {
boolean b = quartzUtil.pauseJob("job1", "group1");
if(b) {
return "success";
}
return "fail";
}
/**
* 立即执行一次任务
* @return
*/
@GetMapping("/testRunOne")
public String testRunOne() {
Job job = new Job();
job.setName("job1");
job.setGroup("group1");
job.setCron("0/5 * * * * ?");
job.setStatus(1);
job.setDesc("测试加人任务并执行一次");
boolean b = quartzUtil.runNow(job);
if(b) {
return "success";
}
return "fail";
}
}
5、测试
当在浏览器中分别输入地址:http://127.0.0.1:8080/testJoin,http://127.0.0.1:8080/testPause,http://127.0.0.1:8080/testRunOne,会在后端打印以下信息:
测试加人任务并执行
2020-03-26 09:58:39.315 INFO 19784 --- [nio-8081-exec-1] com.study.utils.QuartzUtil : 任务:job1开始注入
任务执行了
测试任务:wuyu
我是新任务,我正在执行。。。
测试加人任务并执行:job1
我是新任务,我正在执行。。。
测试加人任务并执行:job1
任务执行了
测试任务:wuyu
2020-03-26 09:58:45.420 INFO 19784 --- [nio-8081-exec-3] com.study.utils.QuartzUtil : 任务:job1暂停
任务执行了
测试任务:wuyu
2020-03-26 09:58:50.769 INFO 19784 --- [nio-8081-exec-5] com.study.utils.QuartzUtil : 任务:job1开始运行
我是新任务,我正在执行。。。
测试加人任务并执行一次:job1
任务执行了
测试任务:wuyu