开发需求:
最近项目中需要用到定时任务的功能,虽然Spring 也自带了一个轻量级的定时任务Timer实现,但感觉不够灵活,功能也不够强大。项目需求动态修改定时任务参数以及定时时间问题,在考虑之后,决定整合更为专业的Quartz来实现定时任务功能。(Demo中删除了NTP方式时间更新工具类,请自行百度)
解决方案:
第一步:首先,当然是添加依赖的jar文件,我的项目是maven管理的,所以要添加如下依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
第二步:编写参数实体对象
import java.util.Date;
/**
* 时间配置实体类
*/
public class TimeConfig{
private String id;
private String ntpIp;
private String ntpPort;
private String timeZone;
private String cronTime;
private String operateMeans;
private Date createTime;
/** 任务名称 */
private String jobName;
/** 任务分组 */
private String jobGroup;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public String getNtpIp() {
return ntpIp;
}
public void setNtpIp(String ntpIp) {
this.ntpIp = ntpIp;
}
public String getNtpPort() {
return ntpPort;
}
public void setNtpPort(String ntpPort) {
this.ntpPort = ntpPort;
}
public String getTimeZone() {
return timeZone;
}
public void setTimeZone(String timeZone) {
this.timeZone = timeZone;
}
public String getCronTime() {
return cronTime;
}
public void setCronTime(String cronTime) {
this.cronTime = cronTime;
}
public String getOperateMeans() {
return operateMeans;
}
public void setOperateMeans(String operateMeans) {
this.operateMeans = operateMeans;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public String getJobGroup() {
return jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
}
其中jobName和jobGroup两个参数是要在动态中作为任务判定使用的参数
第三步:任务运行入口,即Job实现类,在这里我把它看作工厂类(要实现Job接口)
import com.yosuntek.common.utils.SynSystemDateUtils;
import com.yosuntek.modules.sys.entity.TimeConfig;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import java.util.Map;
//@DisallowConcurrentExecution
public class TimeJob implements Job {
@Override
public void execute(JobExecutionContext job) throws JobExecutionException {
TimeConfig timeConfig = (TimeConfig)job.getMergedJobDataMap().get("timeConfig");
String name=timeConfig.getJobName();
String ntpIp = timeConfig.getNtpIp();
String ntpPort = timeConfig.getNtpPort();
String timeZone = timeConfig.getTimeZone();
System.out.println("定时器name:"+name
+",ip:"+ntpIp
+",port:"+ntpPort
+",timeZone:"+timeZone
+"正在运行。。。。。");
int port = Integer.parseInt(ntpPort);
Map<String, Object> map = SynSystemDateUtils.getNetTime(ntpIp, port, timeZone);
String date = (String) map.get("dataStr_");
String time = (String) map.get("timeStr_");
SynSystemDateUtils.updateSysDateTime(date,time);
}
}
本类中主要是通过实现Job接口,重写execute方法,然后通过get方法获取对应的参数对象,来进行一些定时执行的任务逻辑编写
第四步:编写调用接口实现修改,暂停,继续,删除等操作
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/sys/time")
public class TimeController{
/**
* 任务创建与更新(未存在的就创建,已存在的则更新)
*/
@RequestMapping(value="/startQuartz")
@ResponseBody
public Map<String,Object> startQuartz(HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
String jobName = "timeJobName";
String jobGroup = "timeJobGroup";
String ip = request.getParameter("ntpIp");
String port = request.getParameter("ntpPort");
String timeZone = request.getParameter("timeZone");
String cronTime = request.getParameter("cronTime");
TimeConfig timeConfig = new TimeConfig();
timeConfig.setNtpIp(ip.trim());
timeConfig.setNtpPort(port.trim());
timeConfig.setTimeZone(timeZone.trim());
timeConfig.setJobName(jobName.trim());
timeConfig.setJobGroup(jobGroup.trim());
int parseInt = Integer.parseInt(cronTime);
String cron = CronUtil.createLoopCronExpression(1, parseInt);
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = schedulerFactory.getScheduler();
//获取触发器标识
TriggerKey triggerKey = TriggerKey.triggerKey(jobName.trim(), jobGroup.trim());
//获取触发器trigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if(null==trigger){//不存在任务
//创建任务
JobDetail jobDetail = JobBuilder.newJob(TimeJob.class)
.withIdentity(jobName.trim(), jobGroup.trim())
.build();
jobDetail.getJobDataMap().put("timeConfig", timeConfig);
//表达式调度构建器
//这里的时间也可以通过页面传送过来。具体怎么写请看上一篇quartz介绍
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
//按新的cronExpression表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger()
.withIdentity(timeConfig.getJobName(), timeConfig.getJobGroup())
.startNow()//立即生效
.withSchedule(scheduleBuilder)
.build();
scheduler.scheduleJob(jobDetail, trigger);
}else{//存在任务
// Trigger已存在,那么更新相应的定时设置
//表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
//按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder()
.withIdentity(triggerKey)
.startNow()//立即生效
.withSchedule(scheduleBuilder)
.build();
//按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}
//启动定时器
scheduler.start();
} catch (SchedulerException e) {
e.printStackTrace();
}
map.put("msg", "同步时间启动成功");
map.put("code", 200);
return map;
}
/**
* 删除任务
*/
@RequestMapping(value="/removeQuartz")
public void deleteQuartz(HttpServletRequest request,String jobName,String jobGroup){
JobKey jobKey = JobKey.jobKey(jobName.trim(), jobGroup.trim());
System.out.println("删除"+jobName.trim()+"任务");
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = schedulerFactory.getScheduler();
scheduler.deleteJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 暂停任务
*/
@RequestMapping(value="/pauseQuartz")
public void pauseQuartz(HttpServletRequest request,String jobName,String jobGroup){
TimeConfig timeConfig = new TimeConfig();
timeConfig.setJobGroup(jobGroup);
timeConfig.setJobName(jobName);
System.out.println(jobName+","+jobGroup);
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = schedulerFactory.getScheduler();
scheduler.pauseJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
/**
* 恢复任务
*/
@RequestMapping(value="/resumeQuartz")
public void resumeQuartz(HttpServletRequest request,String jobName,String jobGroup){
TimeConfig timeConfig = new TimeConfig();
timeConfig.setJobGroup(jobGroup);
timeConfig.setJobName(jobName);
System.out.println(jobName+","+jobGroup);
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
// 1、创建调度器Scheduler
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = schedulerFactory.getScheduler();
scheduler.resumeJob(jobKey);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}