如有不对的地方请谅解 么么哒~~~ 可以参考一下我的实现
pom依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
创建数据库表 表名QRTZ_quartz_job
application.yml配置
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
comment-prefix: '--'
table-prefix: QRTZ_
cluster-checkin-interval: 20000
job-store:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
useProperties: false
misfireThreshold: 60000
isClustered: false
tablePrefix: QRTZ_
dataSource: quartzDataSource
properties:
org:
quartz:
scheduler:
instanceName: MyScheduler
instanceId: AUTO
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
useProperties: false
misfireThreshold: 60000
isClustered: false
tablePrefix: QRTZ_
plugin:
shutdownhook:
class: org.quartz.plugins.management.ShutdownHookPlugin
cleanShutdown: true
com:
mchange:
v2:
c3p0:
ComboPooledDataSource:
quartzDataSource:
driverClass: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://IP:端口/库?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
user: 账号
password: 密码
maxPoolSize: 20
minPoolSize: 1
acquireIncrement: 1
maxIdleTime: 60000
idleConnectionTestPeriod: 60
写一个bean 在启动项目的时候 查询数据库的job 把cron添加到quartzJob里
这里的 false == CronUtils.isBeforeNow(cronExpression) 是我的工具类等等放在最后
import com.dji.sample.dji.model.entity.QuartzJob;
import com.dji.sample.dji.util.dateformat.CronUtils;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
public class ActivateJob {
@Autowired
private QuartzServiceImpl quartzService;
//启动定时任务改为运行状态
@Bean
public void ActivateJons() throws SchedulerException, ClassNotFoundException {
//System.out.println("我要恢复!");
if (quartzService.getJobAll().size() >0){
List<QuartzJob> allJobs = quartzService.getJobAll();
for (QuartzJob allJob : allJobs) {
String cronExpression = allJob.getCronExpression();
//只执行当前时间之后的飞行任务
if (false == CronUtils.isBeforeNow(cronExpression)){
//添加数据库的job
quartzService.addJob(allJob);
//恢复job定时任务
// quartzService.resumeJob(allJob);
}
}
}
}
}
实现类 QuartzServiceImpl 因为库很简单 所以用的mybatisplus 继承的baseMapper
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dji.sample.dji.dao.QuartzMapper;
import com.dji.sample.dji.model.entity.QuartzJob;
import com.dji.sample.dji.service.IQuartzService;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class QuartzServiceImpl implements IQuartzService {
@Autowired
private Scheduler scheduler;
@Autowired
private QuartzMapper quartzMapper;
/**
* 添加定时任务
*/
public void addJob(QuartzJob job) throws SchedulerException, ClassNotFoundException {
// 创建JobDetail实例,绑定Job实现类
JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getJobClassName()))
.withIdentity(job.getJobName(), job.getGroupName())
.build();
// 设置触发器类型为Cron表达式类型,并绑定Cron表达式规则到触发器上
CronTrigger cronTrigger = TriggerBuilder.newTrigger()
.withIdentity(job.getJobName(), job.getGroupName())
.withSchedule(CronScheduleBuilder.cronSchedule(job.getCronExpression()))
.build();
// 将JobDetail和CronTrigger注册到Scheduler中,并启动调度器
scheduler.scheduleJob(jobDetail, cronTrigger);
if (!scheduler.isShutdown()) {
scheduler.start();
}
}
@Override
public Integer insert(QuartzJob quartzJob) {
return quartzMapper.insert(quartzJob);
}
@Override
public QuartzJob getJob(String id) {
QueryWrapper<QuartzJob> wrapper = new QueryWrapper<QuartzJob>();
wrapper.eq("job_name",id);
wrapper.eq("del",0);
QuartzJob quartzJob = quartzMapper.selectOne(wrapper);
return quartzJob;
}
@Override
public Integer update(QuartzJob quartzJob) {
return quartzMapper.updateById(quartzJob);
}
/**
* 修改定时任务的执行时间
*/
public void modifyJob(QuartzJob job) throws SchedulerException {
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getGroupName());
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
if (cronTrigger == null) {
return;
}
String oldCronExpression = cronTrigger.getCronExpression();
if (!oldCronExpression.equals(job.getCronExpression())) {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
cronTrigger = cronTrigger.getTriggerBuilder()
.withIdentity(triggerKey)
.withSchedule(scheduleBuilder)
.build();
scheduler.rescheduleJob(triggerKey, cronTrigger);
}
}
/**
* 删除定时任务
*/
public void deleteJob(QuartzJob job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
scheduler.deleteJob(jobKey);
}
/**
* 暂停定时任务的执行
*/
public void pauseJob(QuartzJob job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
scheduler.pauseJob(jobKey);
}
/**
* 恢复定时任务的执行
*/
public void resumeJob(QuartzJob job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
scheduler.resumeJob(jobKey);
}
//恢复定时任务
public void checkJobStatus(QuartzJob job) throws SchedulerException {
JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getGroupName());
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
if (jobDetail == null) {
System.out.println("Job does not exist");
} else {
List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
if (triggers != null && triggers.size() > 0) {
for (Trigger trigger : triggers) {
Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
System.out.println("Trigger state: " + triggerState);
}
} else {
System.out.println("No triggers found for the job");
}
}
}
//查询所有job
public List<QuartzJob> getJobAll(){
QueryWrapper<QuartzJob> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("del",0);
List<QuartzJob> quartzJobs = quartzMapper.selectList(objectQueryWrapper);
return quartzJobs;
}
/**
* 获取所有定时任务信息列表
*/
public List<QuartzJob> getAllJobs() throws SchedulerException {
List<QuartzJob> jobs = null;
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
for (String groupName : scheduler.getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(matcher)) {
QuartzJob job = new QuartzJob();
job.setGroupName(groupName);
job.setJobName(jobKey.getName());
TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), groupName);
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
job.setCronExpression(cronTrigger.getCronExpression());
Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey);
if (triggerState.name().equals("NORMAL")) {
job.setStatus(1);
} else {
job.setStatus(0);
}
jobs.add(job);
}
}
return jobs;
}
}
然后就是你的业务代码 当cron到的时候会自动执行
这里是我的业务代码 可以参考 这里我取了一个jobName 是我存job的时候的参数
import com.dji.sample.component.mqtt.model.TopicConst;
import com.dji.sample.component.mqtt.service.IMessageSenderService;
import com.dji.sample.dji.model.entity.AriRouteTask;
import com.dji.sample.dji.service.IAirRouteTaskService;
import com.dji.sample.dji.util.dateformat.CronExpParserUtil;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
public class MyJob implements Job {
@Autowired
private IMessageSenderService iMessageSenderService;
@Autowired
private IAirRouteTaskService iAirRouteTaskService;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
// 执行自己的业务代码
// System.out.println(context);
String jobName = context.getJobDetail().getKey().getName();
AriRouteTask ariRouteTask = iAirRouteTaskService.getAriRouteTask(Integer.valueOf(jobName));
Integer type = ariRouteTask.getType();
HashMap<Object, Object> rmqttMap = new HashMap<>();
rmqttMap.put("code",200);
rmqttMap.put("message","执行航线巡检任务!");
HashMap<String, Object> data = new HashMap<>();
data.put("taskName",ariRouteTask.getTaskName());
data.put("filPathName",ariRouteTask.getFilPathName());
data.put("executiveEquipment",ariRouteTask.getExecutiveEquipment());
data.put("executiveEquipment",CronExpParserUtil.translateToChinese(ariRouteTask.getCron()));
data.put("type",ariRouteTask.getType());
data.put("executionTime",ariRouteTask.getCron());
if(1 == type){
data.put("executionTime",ariRouteTask.getExecutionTime());
}else if (2 == type){
data.put("executionTime",YYMMDDtoCron.convertToDateTime(ariRouteTask.getCron()));
}
else {
data.put("executionTime",CronExpParserUtil.translateToChinese(ariRouteTask.getCron()));
}
data.put("taskId",ariRouteTask.getId());
rmqttMap.put("data",data);
iMessageSenderService.publishMap(TopicConst.AirRoute,rmqttMap);
}
}
然后就是我存的job
这里可是参考 cron是前端传给我的
要注意一点就是添加的时候用quartzService.addJob(quartzJob);把他加到他的quartz里面
修改的时候我用的
quartzService.deleteJob(job); 删除job
quartzService.update(job); 这个是修改数据库的job
quartzService.addJob(job); 从新添加job到quartz
因为我修改一直未生效所以干脆直接删除在添加
//重复执行 cron表达式
else if (3 == type){
Map taskStrategy = (Map)map.get("taskStrategy");
String cron = (String)taskStrategy.get("cron");
if (true == CronUtils.isBeforeNow(cron)){
return ResponseResult.error("请下发当前时间之后的执行时间!");
}
//保存数据
AriRouteTask ariRouteTask = new AriRouteTask();
ariRouteTask.setFileName(airJson.getFileName());
ariRouteTask.setTaskName(taskName);
ariRouteTask.setFilPathName(airJson.getFilePath());
ariRouteTask.setExecutiveEquipment(executiveEquipment);
ariRouteTask.setCron(cron);
ariRouteTask.setType(type);
ariRouteTask.setRouteFileId(airJson.getId());
ariRouteTask.setExecutionTime(CronExpParserUtil.translateToChinese(cron));
ariRouteTask.setCreatTime(yymmdd);
Integer rid = iAirRouteTaskService.saveTask(ariRouteTask);
//设置定时Job
QuartzJob quartzJob = new QuartzJob();
quartzJob.setGroupName("QRTZ_default");
quartzJob.setJobName(rid.toString());
quartzJob.setJobClassName("com.dji.sample.dji.service.impl.job.MyJob");
quartzJob.setCronExpression(cron);
quartzJob.setStatus(1);
quartzJob.setCreateTime(new Date());
quartzService.addJob(quartzJob);
//保存job到数据库
quartzService.insert(quartzJob);
return ResponseResult.success(ResponseResult.builder()
.code(200)
.message("下发航线巡检任务成功!")
.data(null)
.build());
}
看下效果 其他参数可忽略 cron我传入的3秒执行一次
数据库刚刚修改接口设置的数据
然后我的业务代码是mqtt发送消息 可以看到已经三秒执行一次了 如果没有删除这个job 上面的bean就会在启动时查询出来自动执行
然后就是我的工具类 可以直接用
//把yyyy-MM-dd HH:mm:ss格式的字符串转换为cron格式
public static String convertToCron(String dateTimeString) {
try {
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateTime = inputFormat.parse(dateTimeString);
SimpleDateFormat cronFormat = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
return cronFormat.format(dateTime);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//把cron转换成 yyyy-MM-dd HH:mm:ss
public static String convertToDateTime(String cronString) {
try {
SimpleDateFormat cronFormat = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
Date dateTime = cronFormat.parse(cronString);
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return outputFormat.format(dateTime);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//判断cron是当前时间之前还是之后 true之前 false之后
public static boolean isBeforeNow(String cronExpression) {
try {
CronExpression cron = new CronExpression(cronExpression);
Date nextValidTime = cron.getNextValidTimeAfter(new Date());
return nextValidTime == null;
} catch (Exception e) {
return false;
}
}
然后这就是全部流程了 可以参考一下! 如有不对请谅解! 欢迎交流。
//判断cron是当前时间之前还是之后 true之前 false之后
public static boolean isBeforeNow(String cronExpression) {
try {
CronExpression cron = new CronExpression(cronExpression);
Date nextValidTime = cron.getNextValidTimeAfter(new Date());
return nextValidTime == null;
} catch (Exception e) {
return false;
}
}