1、添加quartz依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-quartz --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId><version>2.5.4</version>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version>
</dependency>

2、实现功能源码

2.1 CronTaskRegistrar  Cron任务注册器

package com.shucha.digitalportalbackstage.biz.task.dispatch;import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Component
public class CronTaskRegistrar implements DisposableBean {private final Map<Runnable, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>(16);@Autowiredprivate TaskScheduler taskScheduler;public TaskScheduler getScheduler() {return this.taskScheduler;}/*** 新增定时任务** @param task* @param cronExpression*/public void addCronTask(Runnable task, String cronExpression) {addCronTask(new CronTask(task, cronExpression));}public void addCronTask(CronTask cronTask) {if (cronTask != null) {Runnable task = cronTask.getRunnable();if (this.scheduledTasks.containsKey(task)) {removeCronTask(task);}this.scheduledTasks.put(task, scheduleCronTask(cronTask));}}/*** 移除定时任务** @param task*/public void removeCronTask(Runnable task) {ScheduledTask scheduledTask = this.scheduledTasks.remove(task);if (scheduledTask != null)scheduledTask.cancel();}public ScheduledTask scheduleCronTask(CronTask cronTask) {ScheduledTask scheduledTask = new ScheduledTask();scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());return scheduledTask;}@Overridepublic void destroy() throws Exception {for (ScheduledTask task : this.scheduledTasks.values()) {task.cancel();}this.scheduledTasks.clear();}
}

2.2 ScheduledTask 计划任务

package com.shucha.digitalportalbackstage.biz.task.dispatch;import java.util.concurrent.ScheduledFuture;public class ScheduledTask {public volatile ScheduledFuture<?> future;/*** 取消定时任务*/public void cancel() {ScheduledFuture<?> future = this.future;if (future != null) {future.cancel(true);}}
}

2.3 SchedulingRunnable 调度运行

package com.shucha.digitalportalbackstage.biz.task.dispatch;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;import java.lang.reflect.Method;
import java.util.Objects;public class SchedulingRunnable implements Runnable {private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);private String beanName;private String methodName;private Object[] params;public SchedulingRunnable(String beanName, String methodName) {this(beanName, methodName, null);}public SchedulingRunnable(String beanName, String methodName, Object... params) {this.beanName = beanName;this.methodName = methodName;this.params = params;}@Overridepublic void run() {logger.info("定时任务开始执行 - bean:{},方法:{},参数:{}", beanName, methodName, params);long startTime = System.currentTimeMillis();try {Object target = SpringContextUtils.getBean(beanName);Method method = null;if (null != params && params.length > 0) {Class<?>[] paramCls = new Class[params.length];for (int i = 0; i < params.length; i++) {paramCls[i] = params[i].getClass();}method = target.getClass().getDeclaredMethod(methodName, paramCls);} else {method = target.getClass().getDeclaredMethod(methodName);}ReflectionUtils.makeAccessible(method);if (null != params && params.length > 0) {method.invoke(target, params);} else {method.invoke(target);}} catch (Exception ex) {logger.error(String.format("定时任务执行异常 - bean:%s,方法:%s,参数:%s ", beanName, methodName, params), ex);}long times = System.currentTimeMillis() - startTime;logger.info("定时任务执行结束 - bean:{},方法:{},参数:{},耗时:{} 毫秒", beanName, methodName, params, times);}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;SchedulingRunnable that = (SchedulingRunnable) o;if (params == null) {return beanName.equals(that.beanName) &&methodName.equals(that.methodName) &&that.params == null;}return beanName.equals(that.beanName) &&methodName.equals(that.methodName) &&params.equals(that.params);}@Overridepublic int hashCode() {if (params == null) {return Objects.hash(beanName, methodName);}return Objects.hash(beanName, methodName, params);}
}

2.4 SpringContextUtils

package com.shucha.digitalportalbackstage.biz.task.dispatch;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext = null;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if (SpringContextUtils.applicationContext == null) {SpringContextUtils.applicationContext = applicationContext;}}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}
}

2.5  QuartzConfig 配置和项目启动初始化

package com.shucha.digitalportalbackstage.biz.task.quartz.config;import com.shucha.digitalportalbackstage.biz.model.QuartzJob;
import com.shucha.digitalportalbackstage.biz.service.QuartzJobService;
import com.shucha.digitalportalbackstage.biz.task.quartz.JobFactory;
import com.shucha.digitalportalbackstage.biz.task.quartz.service.QuartzService;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.UUID;@Configuration
public class QuartzConfig {@Autowiredprivate JobFactory jobFactory;@Autowiredprivate QuartzJobService quartzJobService;@Autowiredprivate QuartzService quartzService;@Bean("schedulerFactory")public SchedulerFactoryBean schedulerFactoryBean() throws IOException {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();//设置调度类quartz属性schedulerFactoryBean.setQuartzProperties(quartzProperties());//设置jobFactoryschedulerFactoryBean.setJobFactory(jobFactory);return schedulerFactoryBean;}@Beanpublic Properties quartzProperties() throws IOException {PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();//若不做额外配置,会有默认的配置文件加载 在jar org.quartz里面 有一份quartz.properties//propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));propertiesFactoryBean.afterPropertiesSet();return propertiesFactoryBean.getObject();}@Beanpublic QuartzInitializerListener initializerListener() {return new QuartzInitializerListener();}@Bean("scheduler")public Scheduler scheduler() throws IOException {return schedulerFactoryBean().getScheduler();}@PostConstructpublic void init() {List<QuartzJob> quartzJobList = quartzJobService.lambdaQuery().list();for (QuartzJob q : quartzJobList) {quartzService.addJob(q);}}private static String getUuid() {return UUID.randomUUID().toString().replace("-", "");}
}
QuartzJob实体类
package com.shucha.digitalportalbackstage.biz.model;import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.sdy.common.model.BaseModel;
import com.sdy.common.utils.DateUtil;
import com.shucha.digitalportalbackstage.biz.dto.job.SaveJobDTO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.util.Date;/*** <p>** </p>** @author tqf* @since 2022-03-14*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class QuartzJob extends BaseModel {private static final long serialVersionUID = 1L;/*** UUID*/@ApiModelProperty(value = "UUID")@TableId(value = "job_id", type = IdType.INPUT)private String jobId;/*** 定时任务示例的 class路径*/@ApiModelProperty(value = "定时任务示例的 class路径")private String className;/*** cron表达式*/@ApiModelProperty(value = "cron表达式")private String cronExpression;/*** 定时任务名称*/@ApiModelProperty(value = "定时任务名称")private String jobName;/*** 定时任务组*/@ApiModelProperty(value = "定时任务组")private String jobGroup;/*** 触发器名称*/@ApiModelProperty(value = "触发器名称")private String triggerName;/*** 触发器组*/@ApiModelProperty(value = "触发器组")private String triggerGroup;/*** 参数*/@ApiModelProperty(value = "参数")private String data;/*** 备注*/@ApiModelProperty(value = "备注")private String description;/*** 创建时间*/@ApiModelProperty(value = "创建时间")@JsonFormat(pattern = DateUtil.DATETIME_FORMAT)private Date createTime;/*** 修改时间*/@ApiModelProperty(value = "修改时间")@JsonFormat(pattern = DateUtil.DATETIME_FORMAT)private Date updateTime;public QuartzJob() {}public QuartzJob(SaveJobDTO save) {this.jobId = save.getJobId();this.className = save.getClassName();this.cronExpression = save.getCronExpression();this.jobName = save.getGroup() + save.getId();this.jobGroup = save.getGroup();this.triggerName = save.getGroup() + save.getId();this.triggerGroup = save.getGroup();this.data = JSONObject.toJSONString(save.getData());this.description = save.getDescription();this.createTime = new Date();}
}

2.6 MessageJob 具体的任务调度执行的业务

package com.shucha.digitalportalbackstage.biz.task.quartz.job;import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sdy.common.utils.DateUtil;
import com.shucha.digitalportalbackstage.biz.dto.MaxTimeDTO;
import com.shucha.digitalportalbackstage.biz.mapper.RemindDataMapper;
import com.shucha.digitalportalbackstage.biz.model.*;
import com.shucha.digitalportalbackstage.biz.service.*;
import com.shucha.digitalportalbackstage.biz.utils.SendMsgUtil;
import lombok.SneakyThrows;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;@Component
public class MessageJob implements Job {@Autowiredprivate QuartzJobService quartzJobService;@Autowiredprivate RemindDataService remindDataService;@Autowiredprivate ZzdUserAllService zzdUserAllService;@Autowiredprivate RemindModuleService moduleService;@Autowiredprivate RemindTemplateService templateService;@Autowiredprivate RemindMessageService remindMessageService;@Autowiredprivate RemindDataMapper remindDataMapper;@Autowiredprivate SendMsgUtil sendMsgUtil;private static Pattern pattern = Pattern.compile("(\\$\\{)([\\w]+)(\\})");private static Logger log = LoggerFactory.getLogger(MessageJob.class);@SneakyThrows@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {Date date = new Date();String triggerName = context.getTrigger().getKey().getName();log.info("******"+triggerName+"任务开始执行******");String jobId = context.getJobDetail().getKey().getName();/*jobId = jobId.substring(0, jobId.length() - name.length());String databaseId = name.substring(JobGroupConstants.DATABASE.length());*/RemindData remindData = JSONObject.toJavaObject(JSONObject.parseObject(JSONObject.toJSONString(context.getMergedJobDataMap().get("myValue"))), RemindData.class);if(remindData != null && remindData.getId() != null) {// 查询短信模板RemindTemplate template = templateService.getOne(Wrappers.<RemindTemplate>lambdaQuery().orderByDesc(RemindTemplate::getCreateTime),false);// 1、根据责任人查询姓名String name = "";ZzdUserAll zzdUserAll = zzdUserAllService.getById(remindData.getDutyId());if(zzdUserAll != null) {name = zzdUserAll.getEmployeeName();}// 2、根据模块ID查询模块名称String moduleName = "";RemindModule module = moduleService.getById(remindData.getRemindModuleId());if(module != null) {moduleName = module.getName();}// 3、不同模块查询对应的最新的创建时间和更新时间Integer day = getDay(remindData.getRemindModuleId(), date);// 短信发送文本内容String messageContent = messageContent(template.getContent(), name, moduleName, day);// 执行短信发送Boolean b = sendMsgUtil.sendOneMobileMsg(remindData.getPhone(), messageContent);if(b) {// 更新当前提醒记录的 提醒次数和最新提醒时间RemindData data = remindDataService.getById(remindData.getId());if(data != null) {data.setRemindTime(date).setRemindNumber(data.getRemindNumber() + 1).setRemindTime(date);remindDataService.updateById(data);}// 生成短信发送记录RemindMessage message = new RemindMessage().setContent(messageContent).setCreateTime(date).setRemindDataId(remindData.getId());remindMessageService.save(message);}}log.info("******"+triggerName+"任务执行结束******");}/*** 短信模板通配符替换指定的值* @param content* @param name* @param moduleName* @param day* @return*/public String messageContent(String content, String name, String moduleName, Integer day){log.info("替换前:" +content);Map<String,Object> params = new HashMap<>();params.put("name", name);params.put("module", moduleName);params.put("day", day);//使用的时候建议定义为常量或者字段Matcher m = pattern.matcher(content);StringBuffer stringBuffer = new StringBuffer();while (m.find()) {String group = m.group().replace("$", "").replace("{", "").replace("}", "");if (params.get(group) == null) {continue;}m.appendReplacement(stringBuffer, (String) params.get(group));}m.appendTail(stringBuffer);Matcher m1 = pattern.matcher(stringBuffer.toString());//可以判断出是否替换成功if(!m1.find()){log.info("替换后:"+stringBuffer.toString());}return stringBuffer.toString();}/*** 根据不同模块查询 最新创建时间和最新更新时间 然后和当前时间计算相差天数* @param id* @return*/public int getDay(Long id, Date date){int day = 0;// id对应的不同模块// 1、数智乐清门户-集成入口// 2、数智乐清门户-通知公告// 3、数智乐清门户-宣传报道// 4、数智乐清门户-文明城市创建// 5、数智乐清门户-风险气象资讯// 6、数智乐清门户-疫苗接种// 7、数智乐清门户-重点指标// 8、数智乐清门户-新型城镇化// 9、数智乐清门户-重点项目Date maxTime = null;MaxTimeDTO maxTimeDTO = remindDataMapper.getMaxTime(id);if(maxTimeDTO != null) {Date createTime = maxTimeDTO.getCreateTime();Date updateTime = maxTimeDTO.getUpdateTime();if( createTime != null && updateTime != null){// 计算查看查看那个时间大maxTime = createTime.getTime() - updateTime.getTime() >0 ? createTime : updateTime;}if(updateTime == null) {if(createTime != null) {maxTime = createTime;}}}day =  (int) ((date.getTime() - maxTime.getTime()) / (1000*3600*24));return day;}
}

2.7 QuartzService 服务类

package com.shucha.digitalportalbackstage.biz.task.quartz.service;import com.alibaba.fastjson.JSONObject;
import com.shucha.digitalportalbackstage.biz.model.QuartzJob;public interface QuartzService {/*** 创建Job** @param job*/Boolean addJob(QuartzJob job);/*** 执行Job** @param job*/Boolean runJob(QuartzJob job);/*** 修改Job** @param job*/Boolean updateJob(QuartzJob job);/*** 暂停Job** @param job*/Boolean pauseJob(QuartzJob job);/*** 唤醒Job** @param job*/Boolean resumeJob(QuartzJob job);/*** 删除Job** @param job*/Boolean deleteJob(QuartzJob job);/*** 获取Job** @param job*/JSONObject queryJob(QuartzJob job);
}

2.8 QuartzServiceImpl 实现类

package com.shucha.digitalportalbackstage.biz.task.quartz.service;import com.alibaba.fastjson.JSONObject;
import com.shucha.digitalportalbackstage.biz.model.QuartzJob;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class QuartzServiceImpl implements QuartzService{private static Logger log = LoggerFactory.getLogger(QuartzServiceImpl.class);@Autowired@Qualifier("scheduler")private Scheduler scheduler;@Overridepublic Boolean addJob(QuartzJob job) {try {
//            JSONObject data = job.getData();JSONObject data =JSONObject.parseObject(job.getData());log.info("当前任务携带的业务参数={}", data.toJSONString());JobDataMap jobDataMap = new JobDataMap();jobDataMap.put("myValue", data);String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;JobDetail jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(job.getClassName()))// 指定执行类.withIdentity(jobUnique, job.getJobGroup())// 指定name和group.requestRecovery().withDescription(job.getDescription()).setJobData(jobDataMap).build();// 创建表达式调度构建器CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());// 创建触发器CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(job.getTriggerName(), job.getTriggerGroup()).withDescription(job.getDescription()).withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);scheduler.start();log.info("定时任务[{}]创建成功,开始执行", jobId + jobName);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic Boolean runJob(QuartzJob job) {try {String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;scheduler.triggerJob(JobKey.jobKey(jobUnique,job.getJobGroup()));log.info("定时任务[{}]执行成功", jobUnique);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic Boolean updateJob(QuartzJob job) {try {String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;TriggerKey triggerKey = new TriggerKey(job.getTriggerName(),job.getTriggerGroup());CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());// 重新构件表达式CronTrigger trigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).withDescription(job.getDescription()).build();scheduler.rescheduleJob(triggerKey, trigger);log.info("定时任务[{}]更新成功", jobUnique);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic Boolean pauseJob(QuartzJob job) {try {String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;scheduler.pauseJob(JobKey.jobKey(jobUnique,job.getJobGroup()));log.info("定时任务[{}]暂停成功", jobUnique);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic Boolean resumeJob(QuartzJob job) {try {String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;scheduler.resumeJob(JobKey.jobKey(jobUnique,job.getJobGroup()));log.info("定时任务[{}]唤醒成功", jobUnique);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic Boolean deleteJob(QuartzJob job) {try {String jobId = job.getJobId();String jobName = job.getJobName();String jobUnique = jobId + jobName;scheduler.deleteJob(JobKey.jobKey(jobUnique, job.getJobGroup()));log.info("定时任务[{}]删除成功", jobUnique);return true;} catch (Exception e) {e.printStackTrace();}return false;}@Overridepublic JSONObject queryJob(QuartzJob job) {TriggerKey triggerKey = new TriggerKey(job.getTriggerName(),job.getTriggerGroup());try {CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);if (null == cronTrigger) {return null;}JSONObject jsonObject = new JSONObject();jsonObject.put("expression", cronTrigger.getCronExpression());jsonObject.put("state", scheduler.getTriggerState(triggerKey));jsonObject.put("description", cronTrigger.getDescription());return jsonObject;} catch (Exception e) {e.printStackTrace();}return null;}
}

2.9 JobFactory

package com.shucha.digitalportalbackstage.biz.task.quartz;import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;@Component
public class JobFactory extends AdaptableJobFactory {@Autowiredprivate AutowireCapableBeanFactory beanFactory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {Object jobInstance = super.createJobInstance(bundle);beanFactory.autowireBean(jobInstance);return jobInstance;}
}

2.10 JobGroupConstants

package com.shucha.digitalportalbackstage.biz.task.quartz;import java.util.HashMap;
import java.util.Map;public class JobGroupConstants {private static final Map<String, String> groupClass = new HashMap<>();public static final String MESSAGE = "message";public static final String MESSAGE_CLASS = "com.shucha.digitalportalbackstage.biz.task.quartz.job.MessageJob";static {groupClass.put(MESSAGE, MESSAGE_CLASS);}public static String getGroupClass(String group) {return groupClass.get(group);}
}

2.11 SaveJobDTO 实体类

package com.shucha.digitalportalbackstage.biz.dto.job;import lombok.Data;import java.util.Map;@Data
public class SaveJobDTO {private String jobId;/*** 组*/private String group;private String className;/*** 组对应的表的 主键ID*/private Long id;/*** cron 表达式*/private String cronExpression;/*** 参数*/private Map<String, Object> data;/*** 备注*/private String description;public SaveJobDTO(String group, Long id, String cronExpression, Map<String, Object> data) {this.group = group;this.id = id;this.cronExpression = cronExpression;this.data = data;}public SaveJobDTO() {}
}

2.12 任务调度表结构

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for quartz_job
-- ----------------------------
DROP TABLE IF EXISTS `quartz_job`;
CREATE TABLE `quartz_job`  (`job_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'UUID',`class_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务示例的 class路径',`cron_expression` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'cron表达式',`job_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务名称',`job_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时任务组',`trigger_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '触发器名称',`trigger_group` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '触发器组',`data` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '参数',`description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '备注',`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',`update_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',PRIMARY KEY (`job_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '定时任务表' ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of quartz_job
-- ----------------------------
INSERT INTO `quartz_job` VALUES ('032925693ba04290a133fda816476a1c', 'com.shucha.digitalportalbackstage.biz.task.quartz.job.MessageJob', '0 25 12 15 * ?', 'message5', 'message', 'message5', 'message', '{\"cycleType\":0,\"monthWeek\":\"15\",\"createTime\":1647250687831,\"phone\":\"17816857416\",\"remindNumber\":0,\"createId\":214,\"remindModuleId\":1,\"dutyId\":465,\"id\":5,\"time\":\"12:25\"}', NULL, '2022-03-14 17:38:08', NULL);SET FOREIGN_KEY_CHECKS = 1;

2.13 项目结构

dispath文件夹下的文件可以删除掉,这里没有使用

2.14 源码demo下载

demo源码下载https://download.csdn.net/download/tanqingfu1/84932500

2.15 QuartzJobService

package com.shucha.digitalportalbackstage.biz.service;import com.sdy.common.model.BizException;
import com.sdy.mvc.service.BaseService;
import com.shucha.digitalportalbackstage.biz.dto.job.SaveJobDTO;
import com.shucha.digitalportalbackstage.biz.model.QuartzJob;/*** <p>* 服务类* </p>** @author* @since 2022-03-14*/
public interface QuartzJobService extends BaseService<QuartzJob> {Boolean saveJob(SaveJobDTO save) throws BizException;Boolean deleteJob(Long id, String group);Boolean updateJob(SaveJobDTO save) throws BizException;//    QuartzJob getJobByGroupAndId(String group, Long id);
}

2.16 QuartzJobServiceImpl

package com.shucha.digitalportalbackstage.biz.service.impl;import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.shucha.digitalportalbackstage.biz.dto.job.SaveJobDTO;
import com.shucha.digitalportalbackstage.biz.mapper.QuartzJobMapper;
import com.shucha.digitalportalbackstage.biz.model.QuartzJob;
import com.shucha.digitalportalbackstage.biz.service.QuartzJobService;
import com.shucha.digitalportalbackstage.biz.task.quartz.JobGroupConstants;
import com.shucha.digitalportalbackstage.biz.task.quartz.service.QuartzService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.UUID;/*** <p>* 服务实现类* </p>** @author tqf* @since 2022-03-14*/
@Slf4j
@Service
public class QuartzJobServiceImpl extends BaseServiceImpl<QuartzJob> implements QuartzJobService {@Autowiredprivate QuartzJobMapper quartzJobMapper;@Autowiredprivate QuartzService quartzService;/*** 新增 定时任务** @param saveJob* @return* @throws BizException*/@Overridepublic Boolean saveJob(SaveJobDTO saveJob) throws BizException {String groupClass = JobGroupConstants.getGroupClass(saveJob.getGroup());Assert.isNull(groupClass, "请添加定时任务的Class!");saveJob.setClassName(groupClass);saveJob.setJobId(getUuid());QuartzJob quartzJob = new QuartzJob(saveJob);boolean save = save(quartzJob);Assert.notTrue(save, "新增失败!");return quartzService.addJob(quartzJob);}/*** 删除定时任务** @param id* @param group* @return*/@Overridepublic Boolean deleteJob(Long id, String group) {Boolean b;QuartzJob quartzJob = lambdaQuery().eq(QuartzJob::getJobGroup, group).eq(QuartzJob::getJobName, group + id).one();// 需要判断是否存在定时任务if(quartzJob != null) {removeById(quartzJob.getJobId());b = quartzService.deleteJob(quartzJob);} else {b = true;}return b;}/*** 修改定时任务** @param update* @return* @throws BizException*/@Overridepublic Boolean updateJob(SaveJobDTO update) throws BizException {QuartzJob quartzJob = getById(update.getJobId());Assert.isNull(quartzJob, "定时任务不存在!");lambdaUpdate().eq(QuartzJob::getJobId, update.getJobId()).set(QuartzJob::getCronExpression, update.getCronExpression()).update();quartzJob.setCronExpression(update.getCronExpression());return quartzService.updateJob(quartzJob);}private static String getUuid() {return UUID.randomUUID().toString().replace("-", "");}
}

2.17 定时任务调用

2.17.1 新建定时任务

// 新建定时任务
JSON jsons = (JSON) JSON.toJSON(remindData);
Map<String, Object> paramMap = JSONObject.parseObject(jsons.toString());
quartzJobService.saveJob(new SaveJobDTO(JobGroupConstants.MESSAGE, remindData.getId(), cronExp, paramMap));cronExp 字段是cron表达式,参照下面文章获取
// https://blog.csdn.net/tanqingfu1/article/details/123474993?spm=1001.2014.3001.5502// 下面方法校验cron表达式是否正确
CronExpression.isValidExpression("0 0 29 ? *")

2.17.2 更新定时任务

// 更新定时任务
String jobName = JobGroupConstants.MESSAGE + remindData.getId();
QuartzJob quartzJob = quartzJobService.lambdaQuery().eq(QuartzJob::getJobName, jobName).one();
SaveJobDTO dto = new SaveJobDTO();
dto.setJobId(quartzJob.getJobId());
dto.setCronExpression(cronExp);
quartzJobService.updateJob(dto);cronExp 字段是cron表达式,参照下面文章获取
// https://blog.csdn.net/tanqingfu1/article/details/123474993?spm=1001.2014.3001.5502

2.17.3 删除定时任务

// 删除定时任务
quartzJobService.deleteJob(id, JobGroupConstants.MESSAGE);

Java使用quartz实现任务调度定时任务相关推荐

  1. java 定时任务插件_详解Spring整合Quartz实现动态定时任务

    最近项目中需要用到定时任务的功能,虽然spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 普通定时任务 首先 ...

  2. 使用Spring整合Quartz轻松完成定时任务

    一.背景 上次我们介绍了如何使用Spring Task进行完成定时任务的编写,这次我们使用Spring整合Quartz的方式来再一次实现定时任务的开发,以下奉上开发步骤及注意事项等. 二.开发环境及必 ...

  3. Quartz定时任务调度机制解析(CronTirgger、SimpleTrigger )

    一.Quartz的介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现.该项目于 2009 年被 Terracotta 收购,目前是 Ter ...

  4. C#使用Topshelf和Quartz开发处理定时任务的Windows服务程序

    C#使用Topshelf框架和Quartz开发处理定时任务的Windows服务程序 背景 依赖 C#代码示例 任务调度的配置文件 测试 服务安装.启动.停止.卸载 背景 有些业务是运行在后台,需要界面 ...

  5. Quartz定时器与定时任务知识概括

    Quartz定时器与定时任务知识概括 定时任务调度 其他定时器 Quartz简介 Quartz简单入门 Spring和Quartz集成 SSMM和Quartz集成 Quartz集群 Quartz配置 ...

  6. 【Quartz】任务调度Quartz从入门到入土(史上最详细)

    背景 在项目开发过程中,有时候需要利用定时任务技术来完成某些周期性的任务,比如,定时下载对账单.定时进行数据对比.转换,数据定时入库等等.在最开始的时候部分开发人员习惯直接在项目中硬编码一些定时器. ...

  7. Spring+Quartz定时任务调度

    Spring+Quartz定时任务调度   2011/5 zqhxuyuan@gmail.com 参考文章: http://www.iteye.com/topic/399980 ­ org.sprin ...

  8. 项目ITP(五) spring4.0 整合 Quartz 实现任务调度

    2014-05-16 22:51 by Jeff Li 前言 系列文章:[传送门] 项目需求: 二维码推送到一体机上,给学生签到扫描用. 然后须要的是 上课前20分钟 .幸好在帮带我的学长做 p2p ...

  9. Spring 3整合Quartz 2实现定时任务--转

    常规整合 http://www.meiriyouke.net/?p=82 最近工作中需要用到定时任务的功能,虽然Spring3也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之 ...

最新文章

  1. LeetCode简单题之有效的字母异位词
  2. python爬虫多久能学会-不踩坑的Python爬虫:如何在一个月内学会爬取大规模数据...
  3. Java的I/O笔记(3)
  4. php+防御+xss,PHP防御XSS攻击
  5. 首发:徐亦达老师的机器学习课件及下载(中文目录)
  6. c语言 结构体的,c语言之结构体
  7. redis-cli批量删除时的坑
  8. 想赚钱,赚大钱,必须要有商业思维
  9. Node-介绍与模块化
  10. asp.net网页编程 ASP.NET中绑定枚举类型
  11. Mpass – PHP做Socket服务的解决方案
  12. 如何打印被加密的PDF文件
  13. matlab 生成自回归,Matlab时间序列-AR-自回归.pdf
  14. 使用PHP连接MySQL数据库的代码
  15. RabbitMQ——01安装
  16. 怎么识别手写的文字?办公常备软件说明
  17. php mysql 排班表_要做排班表 灵活性比较强的
  18. html怎么设置两块区域,将两个视频一左一右拼接 可裁剪画面并设置视频画面大小及位置...
  19. 学习 Rust Futures - Future 和 Stream
  20. 计算机科学转金融工程,计算机如何转金融与金融工程

热门文章

  1. 5个非常实用的小程序UI设计模板分享
  2. cf997C. Sky Full of Stars(组合数 容斥)
  3. 数据库SQL语言中,foreign key和references的区别是什么?
  4. 火狐浏览器占用过多内存
  5. C语言数据结构练习——停车场管理系统(使用栈和队列)(草稿的草稿)
  6. 腾讯视频互动直播TUIPusherTUIPlayer集成体验
  7. JUC源码级学习(下)-函数式编程、stream流、jvm等
  8. 机器学习中ROC曲线和AUC评估指标
  9. 通用GPIO驱动和apk(含jni),支持所有GPIO,支持LED控制,支持友善6410/210开发板,支持安卓2.3/4.0,内核2.6/3.0
  10. 动作捕捉技术赋能协作机器人示教学习