引入依赖
- pom.xml依赖引入
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
</dependency>
创建一个定时任务类
- 实现类实现 Job 类
- 类的第一行 com.xf.mall.task 为该类的完全限定名(根据自己定义的类而定)
- 完全限定名 在后面设置定时器时需要使用
package com.xf.mall.task;
import cn.hutool.core.date.DateUtil
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@Slf4j
public class CountTask implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info("定时任务开始------");
log.info("业务逻辑:"+ DateUtil.date());
log.info("定时任务结束------");
}
}
定义一个定时任务参数接收对象
- 可根据业务需求定义更对的参数,并存储在数据库中,存在多个定时器方便管理和设置
@Data
public class TaskInfo implements Serializable {
private static final long serialVersionUID = -8054692082716173379L;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 任务描述
*/
private String jobDescription;
/**
* 任务表达式
*/
private String cronExpression;
/**
* 创建时间
*/
private String createTime;
}
定义定时任务接口类
- 定义操作定时任务的相关实现方法
public interface TaskService {
//添加任务
void addTask(TaskInfo taskInfo) throws SchedulerException;
//修改任务
void editTask(TaskInfo taskInfo);
//删除任务
void deleteJob(String jobName, String jobGroup);
//暂停任务
void pauseJob(String jobName, String jobGroup);
//恢复任务
void resumeJob(String jobName, String jobGroup);
}
实现操作定时任务相关方法
@Slf4j
@Service
public class TaskServiceImpl implements TaskService {
@Autowired
private Scheduler scheduler;
/**
* 添加定时任务
* @param taskInfo 数据对象
*/
@Override
public void addTask(TaskInfo taskInfo) {
String jobName = taskInfo.getJobName(); //任务名称(完全限定名)
String jobGroup =taskInfo.getJobGroup(); //任务分组
String cronExpression =taskInfo.getCronExpression(); //任务表达式
String jobDescription = taskInfo.getJobDescription(); //任务描述
String createTime = DateUtil.formatTime(DateUtil.date()); //当前时间
try {
//判断任务是否存在
if(existJob(taskInfo.getJobName(),taskInfo.getJobGroup())){
log.info("该定时任务已存在");
throw new SchedulerException("该定时任务已存在");
}
//构建触发器
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
//构建任务
JobKey jobKey=new JobKey(jobName,jobGroup);
//构建时间生成器
CronScheduleBuilder scheduleBuilder=CronScheduleBuilder.cronSchedule(cronExpression)
.withMisfireHandlingInstructionDoNothing();
//构建时间触发器
CronTrigger cronTrigger=TriggerBuilder.newTrigger()
.withIdentity(triggerKey).withDescription(createTime)
.withSchedule(scheduleBuilder).build();
//加载定时任务对象
Class<? extends Job> clazz = (Class<? extends Job>) Class.forName(jobName);
//创建任务
JobDetail jobDetail=JobBuilder.newJob(clazz).withIdentity(jobKey)
.withDescription(jobDescription).build();
//加入任务
scheduler.scheduleJob(jobDetail,cronTrigger);
}
catch (Exception e){
LOGGER.info("保存定时任务-->类名不存在或执行表达式错误--->复杂调度" + e.getMessage());
new Exception("类名不存在或执行表达式错误");
}
}
/**
* 修改定时任务
* @param taskInfo 数据对象
*/
@Override
public void editTask(TaskInfo taskInfo) {
String jobName = taskInfo.getJobName();
String jobGroup =taskInfo.getJobGroup();
String cronExpression =taskInfo.getCronExpression();
String jobDescription = taskInfo.getJobDescription();
String createTime = DateUtil.formatTime(DateUtil.date());
try {
if(!existJob(taskInfo.getJobName(),taskInfo.getJobGroup())){
log.info("该定时任务不存在");
throw new SchedulerException("该定时任务不存在");
}
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
JobKey jobKey=new JobKey(jobName,jobGroup);
CronScheduleBuilder scheduleBuilder=CronScheduleBuilder.cronSchedule(cronExpression)
.withMisfireHandlingInstructionDoNothing();
CronTrigger cronTrigger=TriggerBuilder.newTrigger()
.withIdentity(triggerKey).withDescription(createTime)
.withSchedule(scheduleBuilder).build();
//获取定时任务
JobDetail jobDetail=scheduler.getJobDetail(jobKey);
jobDetail.getJobBuilder()
.withDescription(jobDescription);
//重新设置触发器
HashSet<Trigger> hashSet=new HashSet<>();
hashSet.add(cronTrigger);
scheduler.scheduleJob(jobDetail,hashSet,true);
}catch (Exception e){
LOGGER.info("修改定时任务-->类名不存在或执行表达式错误--->复杂调度" + e.getMessage());
new Exception("类名不存在或执行表达式错误");
}
}
/**
* 删除定时任务
* @param jobName 任务名字(完全限定名)
* @param jobGroup 任务分组
*/
@Override
public void deleteJob(String jobName, String jobGroup) {
//创建触发器
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
//创建定时任务
JobKey jobKey =new JobKey(jobName,jobGroup);
try {
if(existJob(jobName,jobGroup)){
//暂停触发器
scheduler.pauseTrigger(triggerKey);
//移除触发器
scheduler.unscheduleJob(triggerKey);
//删除定时任务
scheduler.deleteJob(jobKey);
}
}catch (Exception e){
LOGGER.info("删除定时任务-->类名不存在或执行表达式错误--->复杂调度" + e.getMessage());
new Exception("类名不存在或执行表达式错误");
}
}
/**
* 暂停定时任务
* @param jobName 任务名字(完全限定名)
* @param jobGroup 任务分组
*/
@Override
public void pauseJob(String jobName, String jobGroup) {
//创建触发器
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
//创建定时任务
JobKey jobKey =new JobKey(jobName,jobGroup);
try {
if(existJob(jobName,jobGroup)){
//暂停触发器
scheduler.pauseTrigger(triggerKey);
//删除定时任务
scheduler.pauseJob(jobKey);
}
}catch (Exception e){
LOGGER.info("暂停定时任务-->类名不存在或执行表达式错误--->复杂调度" + e.getMessage());
new Exception("类名不存在或执行表达式错误");
}
}
/**
* 恢复定时任务
* @param jobName 任务名字(完全限定名)
* @param jobGroup 任务分组
*/
@Override
public void resumeJob(String jobName, String jobGroup) {
//创建触发器
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
//创建定时任务
JobKey jobKey =new JobKey(jobName,jobGroup);
try {
if(existJob(jobName,jobGroup)){
//暂停触发器
scheduler.resumeTrigger(triggerKey);
//删除定时任务
scheduler.resumeJob(jobKey);
}
}catch (Exception e){
LOGGER.info("暂停定时任务-->类名不存在或执行表达式错误--->复杂调度" + e.getMessage());
new Exception("类名不存在或执行表达式错误");
}
}
/**
* 校验定时任务是否已存在
* @param jobName
* @param jobGroup
* @return
* @throws SchedulerException
*/
private boolean existJob(String jobName, String jobGroup) throws SchedulerException {
TriggerKey triggerKey=new TriggerKey(jobName,jobGroup);
return scheduler.checkExists(triggerKey);
}
}
接口类定义
- 简单的接口定义,主要用于demo的接口测试。需根据实际业务需求进行字段校验等操作。
/**
* 定时任务控制器
*/
@RestController
@RequestMapping("task")
public class TaskController {
@Autowired
private TaskService taskService;
/**
* 添加定时任务
* @param info 数据对象
* @throws SchedulerException
*/
@PostMapping("/add")
@ResponseBody
public void addTask( TaskInfo info) throws SchedulerException {
taskService.addTask(info);
}
/**
* 修改定时任务
* @param info 数据对象
*/
@PostMapping("/edit")
@ResponseBody
public void editTask( TaskInfo info) {
taskService.editTask(info);
}
/**
* 暂停定时任务
* @param jobName 任务名称(完全限定名)
* @param jobGroup 任务分组
*/
@PostMapping("/pauseJob")
@ResponseBody
public void pauseJob( String jobName,String jobGroup) {
taskService.pauseJob(jobName,jobGroup);
}
/**
* 恢复定时任务
* @param jobName 任务名称(完全限定名)
* @param jobGroup 任务分组
*/
@PostMapping("/resumeJob")
@ResponseBody
public void resumeJob( String jobName,String jobGroup) {
taskService.resumeJob(jobName,jobGroup);
}
/**
* 删除定时任务
* @param jobName 任务名称(完全限定名)
* @param jobGroup 任务分组
*/
@PostMapping("/deleteJob")
@ResponseBody
public void deleteJob(String jobName,String jobGroup) {
taskService.deleteJob(jobName,jobGroup);
}
测试
- 添加定时器
注意:定时任务表达式要严格遵守规范 在线生成地址
这里添加时设置的是3秒执行一次定时任务
- 修改定时任务
注意:完全限定名 和 分组 必须和添加时的一致(下面请求同理)
这里把执行时间修改成了 5秒 执行一次
- 暂停定时任务
- 恢复定时任务
- 删除定时任务
完成。
嗯,今天成都下雪了~~~