springboot环境
标题主要quartz依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<!--<version>${quartz.version}</version>-->
</dependency>
实体类
package com.yuexiufinance.chatgtp.job;
public class MyVo {
private String id;
private String name;
private int age;
public MyVo(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
job的实现类
package com.yuexiufinance.chatgtp.job;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* @author supermiketho
* @date 2023年02月07日
*/
public class DemoJob implements Job {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void execute(JobExecutionContext context){
String taskId = context.getJobDetail().getKey().getName();
logger.info("动态执行提醒计划-》》" + taskId);
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
MyVo myVo = (MyVo)jobDataMap.get("params");
logger.info("动态执行提醒计划 myVo-》getId 》" + myVo.getId());
logger.info("动态执行提醒计划 myVo-》getName 》" + myVo.getName());
logger.info("动态执行提醒计划 myVo-》getAge 》" + myVo.getAge());
}
/**
* 添加任务
* @param cron
* @param taskId
* @param param
*/
public void addJob(String cron,String taskId, Object param){
//添加到任务管理器
QuartzManager.addJob(taskId, cron, param, DemoJob.class);
}
/**
* 删除任务
*
* @param taskId 任务id
*/
public void removeJob(String taskId) {
try {
Map trigger = QuartzManager.getTrigger(taskId);
if(trigger.get("status") == null){
logger.info("已经删除");
return;
}
QuartzManager.removeJob(taskId);
logger.info("删除任务完成");
} catch (Exception e) {
logger.error(">>>>>>>>>>>>>>>>>>>>>>>>删除任务异常:{}", e);
}
}
}
定时器管理类
package com.yuexiufinance.chatgtp.job;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* 定时器管理类
*
* @author supermiketho
*/
public class QuartzManager {
private static final Logger logger = LoggerFactory.getLogger(QuartzManager.class);
private QuartzManager() {
throw new IllegalStateException("Utility class");
}
private static final SchedulerFactory schedulerFactory = new StdSchedulerFactory();
/**
* 默认任务组名
*/
private static final String DEFAULT_JOB_GROUP_NAME = "DEFAULT_JOB_GROUP_NAME";
/**
* 默认触发器名
*/
private static final String DEFAULT_TRIGGER_GROUP_NAME = "DEFAULT_TRIGGER_GROUP_NAME";
/*
*****************************************************************************************************
* 添加
*****************************************************************************************************
*/
/**
* 添加定时任务(使用默认任务组名,触发器名,触发器组名)
*
* @param jobName 任务名
* @param cronExpression 时间表达式
* @param params 参数
* @param jobClass 定时器工作类
*/
public static void addJob(String jobName, String cronExpression, Object params, Class<? extends Job> jobClass) {
try {
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, DEFAULT_JOB_GROUP_NAME).build();
jobDetail.getJobDataMap().put("params", params); // 添加参数
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
// 按新的cronExpression表达式构建一个新的trigger
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, DEFAULT_TRIGGER_GROUP_NAME)
.withSchedule(cronScheduleBuilder).build();
// 交给scheduler去调度
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(jobDetail, trigger);
if (!scheduler.isShutdown()) { // 启动
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>启动任务[{}]", jobName);
scheduler.start();
}
} catch (Exception e) {
e.printStackTrace();
//throw new ServiceException(e);
}
}
/*
*****************************************************************************************************
* 修改
*****************************************************************************************************
*/
/**
* 修改任务触发时间(使用默认的任务组名,触发器名,触发器组名)
*
* @param jobName 任务名
* @param cronExpression 时间表达式
*/
public static void updateCronExpression(String jobName, String cronExpression) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, DEFAULT_TRIGGER_GROUP_NAME);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (cronTrigger == null) {
return;
}
String oldCronExpression = cronTrigger.getCronExpression();
if (!oldCronExpression.equalsIgnoreCase(cronExpression)) {
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
// 按新的cronExpression表达式重新构建trigger
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder)
.build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, cronTrigger);
}
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/**
* 修改任务触发时间
*
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cronExpression 时间表达式
*/
public static void updateCronExpression(String triggerName, String triggerGroupName, String cronExpression) {
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (cronTrigger == null) {
return;
}
String oldCronExpression = cronTrigger.getCronExpression();
if (!oldCronExpression.equalsIgnoreCase(cronExpression)) {
// trigger已存在,则更新相应的定时设置
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
// 按新的cronExpression表达式重新构建trigger
cronTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.resumeTrigger(triggerKey);
}
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/*
*****************************************************************************************************
* 删除
*****************************************************************************************************
*/
/**
* 移除任务(使用默认的任务组名,触发器名,触发器组名)
*
* @param jobName 任务名
*/
public static void removeJob(String jobName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, DEFAULT_TRIGGER_GROUP_NAME);
JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP_NAME);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
Trigger trigger = scheduler.getTrigger(triggerKey);
if (trigger == null) {
return;
}
scheduler.pauseTrigger(triggerKey); // 停止触发器
scheduler.unscheduleJob(triggerKey); // 移除触发器
scheduler.deleteJob(jobKey); // 删除任务
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>移除任务[{}]", jobName);
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/**
* 移除任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
*/
public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, triggerGroupName);
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.pauseTrigger(triggerKey);// 停止触发器
scheduler.unscheduleJob(triggerKey);// 移除触发器
scheduler.deleteJob(jobKey);// 删除任务
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>移除任务[{}]", jobName);
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/*
*****************************************************************************************************
* 暂停
*****************************************************************************************************
*/
/**
* 暂停任务(使用默认组名)
*
* @param jobName 任务名
*/
public static void pauseJob(String jobName) {
pauseJob(jobName, DEFAULT_JOB_GROUP_NAME);
}
/**
* 暂停任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
*/
public static void pauseJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.pauseJob(jobKey);
TriggerKey triggerKey = TriggerKey.triggerKey(jobName,jobGroupName);
logger.info("操作停止任务【"+jobName+"】,状态"+scheduler.getTriggerState(triggerKey));
} catch (SchedulerException e) {
//throw new ServiceException(e);
}
}
/*
*****************************************************************************************************
* 启动
*****************************************************************************************************
*/
/**
* 恢复任务(使用默认组名)
*
* @param jobName 任务名
*/
public static void resumeJob(String jobName) {
resumeJob(jobName, DEFAULT_JOB_GROUP_NAME);
}
/**
* 恢复任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
*/
public static void resumeJob(String jobName, String jobGroupName) {
JobKey jobKey = JobKey.jobKey(jobName, jobGroupName);
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.resumeJob(jobKey);
TriggerKey triggerKey = TriggerKey.triggerKey(jobName,jobGroupName);
logger.info("操作恢复任务【"+jobName+"】,状态"+scheduler.getTriggerState(triggerKey));
} catch (SchedulerException e) {
//throw new ServiceException(e);
}
}
/**
* 启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.start();
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/*
*****************************************************************************************************
* 关闭
*****************************************************************************************************
*/
/**
* 关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
if (!scheduler.isShutdown()) {
scheduler.shutdown();
}
} catch (Exception e) {
//throw new ServiceException(e);
}
}
/**
* 获取job数量
*
* @return
*/
public static int getJobSize() {
try {
Scheduler scheduler = schedulerFactory.getScheduler();
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.anyGroup());
return jobKeys.size();
} catch (SchedulerException e) {
logger.error("获取job size 异常{}", e);
}
return 0;
}
/**
* 获取调度任务
*
* @param jobName 任务名
*/
public static Map<String,String> getTrigger(String jobName) {
Map<String,String> result = new HashMap<String,String>();
result.put("msg", "没有查到任务【"+jobName+"】");
try {
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, DEFAULT_TRIGGER_GROUP_NAME);
Scheduler scheduler = schedulerFactory.getScheduler();
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (cronTrigger == null) {
logger.info("当前不存在调度任务jobName【"+jobName+"】");
return result;
}
//logger.info("当前存在调度任务jobName【"+jobName+"】,cron【"+cronTrigger.getCronExpression()+"】,状态"+scheduler.getTriggerState(triggerKey));
result.put("jobName", jobName);
result.put("cron", cronTrigger.getCronExpression());
result.put("status", scheduler.getTriggerState(triggerKey).toString());
result.put("msg", "有执行任务【"+jobName+"】");
return result;
} catch (Exception e) {
logger.info("查询调度任务报错:"+e);
}
return result;
}
}
工具类QuartzDateUtil
package com.yuexiufinance.chatgtp.job;
import org.springframework.util.Assert;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class QuartzDateUtil {
/***
* 功能描述:日期转换cron表达式
* @param date
* @param dateFormat : e.g:yyyy-MM-dd HH:mm:ss
* @return
*/
public static String formatDateByPattern(Date date, String dateFormat){
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
String formatTimeStr = null;
if (date != null) {
formatTimeStr = sdf.format(date);
}
return formatTimeStr;
}
/***
* convert Date to cron ,eg. "0 07 10 15 1 ? 2016"
* @param date : 时间点
* @param addMinute : 延时多少分钟
* @return
*/
public static String getCron(Date date,int addMinute){
date = addMinute(date,addMinute);
String dateFormat="ss mm HH dd MM ? yyyy";
return formatDateByPattern(date, dateFormat);
}
/**
* 分钟加减
*
* @param date
* @param minute
* @return
*/
public static Date addMinute(Date date, int minute) {
Assert.notNull(date, "参数[date]不能为空");
return addTime(date, 0, 0, 0, 0, minute, 0);
}
/**
* 获取日期加减(年 && 月 && 日 && 时 && 分 && 秒)后的日期(24小时制)
* <p>
* 相减使用负数表示
*
* @param date 要加减的日期
* @param year 加减<年>数
* @param month 加减<月>数
* @param day 加减<日>数
* @param hour 加减<时>数
* @param minute 加减<分>数
* @param second 加减<秒>数
* @return 加减后的日期
*/
public static Date addTime(Date date, int year, int month, int day, int hour, int minute, int second) {
Assert.notNull(date, "参数[date]不能为空");
Calendar calender = toCalendar(date);
calender.add(Calendar.YEAR, year);
calender.add(Calendar.MONTH, month);
calender.add(Calendar.DAY_OF_MONTH, day); // DAY_OF_MONTH=DATE
calender.add(Calendar.HOUR_OF_DAY, hour); // HOUR_OF_DAY:24小时制;HOUR:12小时制
calender.add(Calendar.MINUTE, minute);
calender.add(Calendar.SECOND, second);
return calender.getTime();
}
public static Calendar toCalendar(Date date) {
Assert.notNull(date, "参数[date]不能为空");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar;
}
}
## 测试接口类:TestController`
package com.yuexiufinance.chatgtp.job;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/")
@Slf4j
public class TestController {
@GetMapping("/test")
public String test() {
DemoJob job = new DemoJob();
MyVo param = new MyVo("123456", "张三", 28);
String cron = QuartzDateUtil.getCron(new Date(), 1);
System.out.println(cron);
QuartzManager.addJob(param.getId(), cron, param, DemoJob.class);
return "{" + "code: 1000," + "msg: \"操作成功\"," + "data: \"\"" + "}";
}
@GetMapping("/removeJob")
public String removeJob() {
DemoJob job = new DemoJob();
job.removeJob("123456");
return "{" + "code: 1000," + "msg: \"操作成功\"," + "data: \"\"" + "}";
}
}
## 添加任务接口调:
```java
http://127.0.0.1:8080/test

DemoJob执行结果
