国内电子商务网站有哪些,建设一个网站需要哪些,wordpress 新建文章,wordpress输出标签名称生命无罪#xff0c;健康万岁#xff0c;我是laity。
我曾七次鄙视自己的灵魂#xff1a;
第一次#xff0c;当它本可进取时#xff0c;却故作谦卑#xff1b;
第二次#xff0c;当它在空虚时#xff0c;用爱欲来填充#xff1b;
第三次#xff0c;在困难和容易之…生命无罪健康万岁我是laity。
我曾七次鄙视自己的灵魂
第一次当它本可进取时却故作谦卑
第二次当它在空虚时用爱欲来填充
第三次在困难和容易之间它选择了容易
第四次它犯了错却借由别人也会犯错来宽慰自己
第五次它自由软弱却把它认为是生命的坚韧
第六次当它鄙夷一张丑恶的嘴脸时却不知那正是自己面具中的一副
第七次它侧身于生活的污泥中虽不甘心却又畏首畏尾。 本文带各位学习下Quartz的基本使用及业务中的整合包括基本概念以及如何动态地对定时任务进行CRUD并且如何实现定时任务的持久化以及任务恢复其中分享下本人在使用时遇到的问题和解决方案。 Quartz的基本使用 Quartz 是一个开源的作业调度框架,支持分布式定时任务Quartz定时任务据我了解可分为Trigger触发器、Job任务和Scheduler调度器定时任务的逻辑大体为创建触发器和任务并将其加入到调度器中。 Quartz 的核心类有以下三部分
任务 Job 需要实现的任务类实现 execute() 方法执行后完成任务;触发器 Trigger 包括 SimpleTrigger 和 CronTrigger;调度器 Scheduler 任务调度器负责基于 Trigger触发器来执行 Job任务. Trigger 有五种触发器
SimpleTrigger 触发器需要在特定的日期/时间启动且以指定的间隔时间单位毫秒重复执行 n 次任务如 在 9:00 开始每隔1小时每隔几分钟每隔几秒钟执行一次 。没办法指定每隔一个月执行一次每月的时间间隔不是固定值。CalendarIntervalTrigger 触发器指定从某一个时间开始以一定的时间间隔单位有秒分钟小时天月年星期执行的任务。DailyTimeIntervalTrigger 触发器指定每天的某个时间段内以一定的时间间隔执行任务。并且支持指定星期。如指定每天 9:00 至 18:00 每隔 70 秒执行一次并且只要周一至周五执行。CronTrigger 触发器基于日历的任务调度器即指定星期、日期的某时间执行任务。NthIncludedDayTrigger 触发器不同时间间隔的第 n 天执行任务。比如在每个月的第 15 日处理财务发票记帐同样设定双休日或者假期。
使用场景
发布消息、问卷等信息时发布者可以指定星期、月份的具体时间进行定时发布cron 触发器设置当天或指定日期的时间范围内指定时间间隔执行任务。其他定时功能可根据不同的任务触发器进行实现。
依赖的引入 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-quartz/artifactId/dependency简单的测试 将job封装给jobDetail,由调度器scheudler根据触发器trggier条件触发相应的jobDetail,每次触发都会让jobDetail重新创建job对象,并且jobDetail会将数据传给job 有两种方式: 1.jobDetail会根据自己usingJobData中的参数主动调用job对应的set方法,设置给job使用。 2.*job可以从重写方法传过来的参数jobExecutionContext中获取jobDetail*然后从jobDetail中获取到jobDataMap。 /*** author: Laity* Project: JavaLaity* Description: 测试定时任务并获取自定义参数*/public class MyJob implements Job {Overridepublic void execute(JobExecutionContext content) throws JobExecutionException {long count (long) content.getJobDetail().getJobDataMap().get(count);System.out.println(当前执行第 count 次);content.getJobDetail().getJobDataMap().put(count, count);System.out.println(任务执行.....);}public static void main(String[] args) throws Exception {// 1.创建调度器 SchedulerSchedulerFactory factory new StdSchedulerFactory();Scheduler scheduler factory.getScheduler();// 2.创建JobDetail实例并与MyJob类绑定(Job执行内容)JobDetail job JobBuilder.newJob(MyJob.class).withIdentity(job1, group1).usingJobData(count, 1L).build();// 3.构建Trigger实例,每隔3s执行一次Trigger trigger TriggerBuilder.newTrigger().withIdentity(trigger1, group1).startNow().withSchedule(simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();// 4.执行开启调度器scheduler.scheduleJob(job, trigger);System.out.println(System.currentTimeMillis());scheduler.start();//主线程睡眠1分钟然后关闭调度器TimeUnit.MINUTES.sleep(1);scheduler.shutdown();System.out.println(System.currentTimeMillis());}
}Quartz高级使用 当遇到更新版本等情况时肯定要将程序给停了但是程序停止后那些还未开始或者没执行完的定时任务就没了。所以我们需要将任务持久化到数据库中然后在程序启动时将这些任务进行恢复。 数据库表设计
官方提供了一份数据库表设计有兴趣的小伙伴可以去下载
DROP TABLE IF EXISTS quartz_entity;
CREATE TABLE quartz_entity (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,job_name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 任务名,group_name varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT 任务分组,start_time timestamp DEFAULT NULL COMMENT 任务开始时间,end_time timestamp DEFAULT NULL COMMENT 任务结束时间,job_class varchar(255) DEFAULT NULL COMMENT 定时任务所在的类,cron varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT cron表达式,job_data_map_json varchar(255) DEFAULT NULL COMMENT json格式的jobDataMap,status varchar(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 0 COMMENT 任务状态。0-进行中1-已完成2-取消, PRIMARY KEY (id) USING BTREE
) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COMMENT定时任务信息;SET FOREIGN_KEY_CHECKS 1;application-local.yml配置
spring:info:build:encoding: UTF-8datasource:dynamic:druid:initial-size: 10# 初始化大小最小最大min-idle: 20maxActive: 500# 配置获取连接等待超时的时间maxWait: 60000# 配置间隔多久才进行一次检测检测需要关闭的空闲连接单位是毫秒timeBetweenEvictionRunsMillis: 60000# 配置一个连接在池中最小生存的时间单位是毫秒minEvictableIdleTimeMillis: 300000testWhileIdle: truetestOnBorrow: truevalidation-query: SELECT 1testOnReturn: false# 打开PSCache并且指定每个连接上PSCache的大小poolPreparedStatements: truemaxPoolPreparedStatementPerConnectionSize: 20filters: stat,wallfilter:wall:config:multi-statement-allow: truenone-base-statement-allow: trueenabled: true# 配置DruidStatFilterweb-stat-filter:enabled: trueurl-pattern: /*exclusions: *.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*# 配置DruidStatViewServletstat-view-servlet:enabled: trueurl-pattern: /druid/*allow:deny:reset-enable: falselogin-username: adminlogin-password: 111111query-timeout: 36000primary: slavestrict: falsedatasource:master:url: jdbc:mysql://127.0.0.1:3306/jxgl?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8useSSLfalseallowPublicKeyRetrievaltrueusername: rootpassword: wang9264driver-class-name: com.mysql.jdbc.Driverslave:url: jdbc:mysql://127.0.0.1:3306/java?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8useSSLfalseallowPublicKeyRetrievaltrueusername: rootpassword: wang9264driver-class-name: com.mysql.jdbc.Driver实体类的创建
/*** author: Laity* Project: JavaLaity*/Data
public class QuartzEntity {TableId(value id,type IdType.AUTO)private Long id;private String jobName;private String groupName;private Date startTime;private Date endTime;private String jobClass;private String cron;private String jobDataMapJson;private String status;}service层
/*** author: Laity* Project: JavaLaity*/public interface QuartzService {void save(QuartzEntity entity);boolean modifyJob(QuartzEntity entity);boolean modifyTaskStatus(String jobName,String status);ListQuartzEntity notStartOrNotEndJobs();
}serviceImpl层
/*** author: Laity* Project: JavaLaity*/
Service(quartzService)
public class QuartzServiceImpl implements QuartzService {Resourceprivate QuartzDao quartzMapper;Overridepublic void save(QuartzEntity entity) {quartzMapper.insert(entity);}Overridepublic boolean modifyJob(QuartzEntity entity) {LambdaQueryWrapperQuartzEntity wrapper new LambdaQueryWrapper();wrapper.eq(QuartzEntity::getJobName, entity.getJobName());QuartzEntity one quartzMapper.selectOne(wrapper);if (one ! null) {entity.setId(one.getId());return quartzMapper.updateById(entity) 0;}return false;}Overridepublic boolean modifyTaskStatus(String jobName, String status) {LambdaQueryWrapperQuartzEntity wrapper new LambdaQueryWrapper();wrapper.eq(QuartzEntity::getJobName, jobName);QuartzEntity one quartzMapper.selectOne(wrapper);if (one ! null) {one.setStatus(status);return quartzMapper.updateById(one) 0;}return false;}Overridepublic ListQuartzEntity notStartOrNotEndJobs() {return quartzMapper.notStartOrNotEndJobs();}
}Dao层
/*** author: Laity* Project: JavaLaity*/
Mapper
public interface QuartzDao extends BaseMapperQuartzEntity {Select(SELECT * FROM quartz_entity WHERE ( end_time IS NULL // 没有结束时间的 OR ( start_time NOW() AND end_time NOW()) // 已经开始但未结束的 OR start_time NOW() // 还未开始的 ) AND status 0)ListQuartzEntity notStartOrNotEndJobs();
}封装组件
QuartzUtil.java 封装了 定时任务的创建、定时任务的修改、定时任务的结束、定时任务的查询、定时任务的恢复(重启服务的时候使用) /*** author: Laity* Project: JavaLaity*/
Component
public class QuartzUtil {private static final SchedulerFactory SCHEDULER_FACTORY new StdSchedulerFactory();Autowiredprivate QuartzService quartzService;/*** 添加一个定时任务** param name 任务名。每个任务唯一不能重复。方便起见触发器名也设为这个* param group 任务分组。方便起见触发器分组也设为这个* param jobClass 任务的类类型 eg:MyJob.class* param startTime 任务开始时间。传null就是立即开始* param endTime 任务结束时间。如果是一次性任务或永久执行的任务就传null* param cron 时间设置表达式。传null就是一次性任务*/public boolean addJob(String name, String group, Class? extends Job jobClass,Date startTime, Date endTime, String cron, JobDataMap jobDataMap) {try {// 第一步: 定义一个JobDetailJobDetail jobDetail JobBuilder.newJob(jobClass).withIdentity(name, group).setJobData(jobDataMap).build();// 第二步: 设置触发器TriggerBuilderTrigger triggerBuilder newTrigger();triggerBuilder.withIdentity(name, group);triggerBuilder.startAt(toStartDate(startTime));triggerBuilder.endAt(toEndDate(endTime)); //设为null则表示不会停止if (StrUtil.isNotEmpty(cron)) {triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));}Trigger trigger triggerBuilder.build();//第三步调度器设置Scheduler scheduler SCHEDULER_FACTORY.getScheduler();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();}} catch (Exception e) {e.printStackTrace();return false;}//存储到数据库中QuartzEntity entity new QuartzEntity();entity.setJobName(name);entity.setGroupName(group);entity.setStartTime(startTime ! null ? startTime : new Date());entity.setEndTime(endTime);entity.setJobClass(jobClass.getName());entity.setCron(cron);entity.setJobDataMapJson(JSONUtil.toJsonStr(jobDataMap));entity.setStatus(0);quartzService.save(entity);return true;}/*** 修改一个任务的开始时间、结束时间、cron。不改的就传null** param name 任务名。每个任务唯一不能重复。方便起见触发器名也设为这个* param group 任务分组。方便起见触发器分组也设为这个* param newStartTime 新的开始时间* param newEndTime 新的结束时间* param cron 新的时间表达式*/public boolean modifyJobTime(String name, String group, Date newStartTime,Date newEndTime, String cron) {try {Scheduler scheduler SCHEDULER_FACTORY.getScheduler();TriggerKey triggerKey TriggerKey.triggerKey(name, group);Trigger oldTrigger scheduler.getTrigger(triggerKey);if (oldTrigger null) {return false;}TriggerBuilderTrigger triggerBuilder newTrigger();triggerBuilder.withIdentity(name, group);if (newStartTime ! null) {triggerBuilder.startAt(toStartDate(newStartTime)); // 任务开始时间设定} else if (oldTrigger.getStartTime() ! null) {triggerBuilder.startAt(oldTrigger.getStartTime()); //没有传入新的开始时间就不变}if (newEndTime ! null) {triggerBuilder.endAt(toEndDate(newEndTime)); // 任务结束时间设定} else if (oldTrigger.getEndTime() ! null) {triggerBuilder.endAt(oldTrigger.getEndTime()); //没有传入新的结束时间就不变}if (StrUtil.isNotEmpty(cron)) {triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));} else if (oldTrigger instanceof CronTrigger) {String oldCron ((CronTrigger) oldTrigger).getCronExpression();triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(oldCron));}Trigger newTrigger triggerBuilder.build();scheduler.rescheduleJob(triggerKey, newTrigger); // 修改触发时间} catch (Exception e) {e.printStackTrace();return false;}// 修改数据库中的记录QuartzEntity entity new QuartzEntity();entity.setJobName(name);entity.setGroupName(group);if (newStartTime ! null) {entity.setStartTime(newStartTime);}if (newEndTime ! null) {entity.setEndTime(newEndTime);}if (StrUtil.isNotEmpty(cron)) {entity.setCron(cron);}return quartzService.modifyJob(entity);}/*** 结束任务* param jobName 任务名称* param groupName 分组名称* return boolean*/public boolean cancelJob(String jobName, String groupName) {try {Scheduler scheduler SCHEDULER_FACTORY.getScheduler();TriggerKey triggerKey TriggerKey.triggerKey(jobName, groupName);scheduler.pauseTrigger(triggerKey); // 停止触发器scheduler.unscheduleJob(triggerKey); // 移除触发器scheduler.deleteJob(JobKey.jobKey(jobName, groupName)); // 删除任务} catch (Exception e) {e.printStackTrace();return false;}//将数据库中的任务状态设为 取消return quartzService.modifyTaskStatus(jobName, 2);}/*** 获取所有job任务信息* return list* throws SchedulerException error*/public ListQuartzEntity getAllJobs() throws SchedulerException {Scheduler scheduler SCHEDULER_FACTORY.getScheduler();ListQuartzEntity quartzJobs new ArrayList();try {ListString triggerGroupNames scheduler.getTriggerGroupNames();for (String groupName : triggerGroupNames) {GroupMatcherTriggerKey groupMatcher GroupMatcher.groupEquals(groupName);SetTriggerKey triggerKeySet scheduler.getTriggerKeys(groupMatcher);for (TriggerKey triggerKey : triggerKeySet) {Trigger trigger scheduler.getTrigger(triggerKey);JobKey jobKey trigger.getJobKey();JobDetail jobDetail scheduler.getJobDetail(jobKey);//组装数据QuartzEntity entity new QuartzEntity();entity.setJobName(jobDetail.getKey().getName());entity.setGroupName(jobDetail.getKey().getGroup());entity.setStartTime(trigger.getStartTime());entity.setEndTime(trigger.getStartTime());entity.setJobClass(jobDetail.getJobClass().getName());if (trigger instanceof CronTrigger) {entity.setCron(((CronTrigger) trigger).getCronExpression());}entity.setJobDataMapJson(JSONUtil.toJsonStr(jobDetail.getJobDataMap()));quartzJobs.add(entity);}}} catch (Exception e) {e.printStackTrace();}return quartzJobs;}public void recoveryAllJob() {ListQuartzEntity tasks quartzService.notStartOrNotEndJobs();if (tasks ! null tasks.size() 0) {for (QuartzEntity task : tasks) {try {JobDataMap jobDataMap JSONUtil.toBean(task.getJobDataMapJson(), JobDataMap.class);JobDetail jobDetail JobBuilder.newJob((Class? extends Job) Class.forName(task.getJobClass())).withIdentity(task.getJobName(), task.getGroupName()).setJobData(jobDataMap).build();TriggerBuilderTrigger triggerBuilder TriggerBuilder.newTrigger();triggerBuilder.withIdentity(task.getJobName(), task.getGroupName());triggerBuilder.startAt(toStartDate(task.getStartTime()));triggerBuilder.endAt(toEndDate(task.getEndTime()));if (StrUtil.isNotEmpty(task.getCron())) {triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(task.getCron()));}Trigger trigger triggerBuilder.build();Scheduler scheduler SCHEDULER_FACTORY.getScheduler();scheduler.scheduleJob(jobDetail, trigger);if (!scheduler.isShutdown()) {scheduler.start();}} catch (Exception e) {e.printStackTrace();}}}}private static Date toEndDate(Date endDateTime) {// endDateTime为null时转换会报空指针异常所以需要进行null判断。// 结束时间可以为null所以endDateTime为null直接返回null即可return endDateTime ! null ?DateUtil.date(endDateTime) : null;}private static Date toStartDate(Date startDateTime) {// startDateTime为空时返回当前时间表示立即开始return startDateTime ! null ?DateUtil.date(startDateTime) : new Date();}
}SpringContextJobUtil.java 用于获取Bean /*** author: Laity* Project: JavaLaity*/Component
public class SpringContextJobUtil implements ApplicationContextAware {private static ApplicationContext context;OverrideSuppressWarnings(static-access)public void setApplicationContext(ApplicationContext context)throws BeansException {this.context context;}public static Object getBean(String beanName) {return context.getBean(beanName);}
}CronUtil.java 你不可能让用户来输入cron表达式所以根据用户的选择来解析成cron表达式 package com.ys.control_core.util.job;import org.apache.commons.lang3.StringUtils;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;/*** author: Laity* Project: JavaLaity* Description: 用于生成Cron表达式*/public class CronUtil {/*** 每天*/private static final int DAY_JOB_TYPE 1;/*** 每周*/private static final int WEEK_JOB_TYPE 2;/*** 每月*/private static final int MONTH_JOB_TYPE 3;/*** 构建Cron表达式** param jobType 作业类型: 1/每天; 2/每周; 3/每月* param minute 指定分钟* param hour 指定小时* param lastDayOfMonth 指定一个月的最后一天0/不指定1/指定* param weekDays 指定一周哪几天1/星期天; 2/...3/.. ; 7/星期六* param monthDays 指定一个月的哪几天* return String*/public static String createCronExpression(Integer jobType, Integer minute, Integer hour, Integer lastDayOfMonth, ListInteger weekDays, ListInteger monthDays) {StringBuilder cronExp new StringBuilder();// 秒cronExp.append(0 );// 指定分钟为空则默认0分cronExp.append(minute null ? 0 : minute).append( );// 指定小时为空则默认0时cronExp.append(hour null ? 0 : hour).append( );// 每天if (jobType DAY_JOB_TYPE) {// 日cronExp.append(* );// 月cronExp.append(* );// 周cronExp.append(?);} else if (lastDayOfMonth ! null lastDayOfMonth 1) {// 日cronExp.append(L );// 月cronExp.append(* );// 周cronExp.append(?);}// 按每周else if (weekDays ! null jobType WEEK_JOB_TYPE) {// 日cronExp.append(? );// 月cronExp.append(* );// 一个周的哪几天cronExp.append(StringUtils.join(weekDays, ,));}// 按每月else if (monthDays ! null jobType MONTH_JOB_TYPE) {// 日cronExp.append(StringUtils.join(monthDays, ,)).append( );// 月cronExp.append(* );// 周cronExp.append(?);} else {cronExp.append(* ).append(* ).append(?);}return cronExp.toString();}public static void main(String[] args) {String cronExpression createCronExpression(1, 26, null, null, null, null);createCronExpression(2, 26, 9, 0, null, null);// 0/2 * * * * ?System.out.println(cronExpression);}/*{jobType:2,times:[{minute:30,hour:8},{minute:00,hour:20}],weekDays:[1,2]}*/
}ValidCron.java 用于检验Cron表达式的正确性 /*** author: Laity* Project: JavaLaity*/
public class ValidCronUtil {public static boolean isValidCronExpression(String exp) {if (exp null || exp.length() 0) return false;boolean validExpression CronExpression.isValidExpression(exp);if (validExpression) System.out.println(cron expression is valid.);return validExpression;}public static void main(String[] args) {String cron 0 26 9 ? * 1,2,3,4,5;boolean validCronExpression isValidCronExpression(cron);System.out.println(validCronExpression);}
}Controller层
/*** author: Laity* Project: JavaLaity*/
RestController
RequestMapping(/quartz/web)
Api(tags 定时任务相关接口API)
public class QuartzWebController {Autowiredprivate QuartzUtil quartzUtil;Autowiredprivate QuartzWebService quartzWebService;PostMapping(/add-job)ApiOperation(value 添加任务, notes 添加任务, httpMethod POST)public Rs AddQuartz(Valid RequestBody CreateJobParam entity) {JobDataMap jobDataMap getJobDataMap(entity);String exp CronUtil.createCronExpression(2, (Integer) jobDataMap.get(minute), (Integer) jobDataMap.get(hour), null, (ListInteger) jobDataMap.get(weekDays), null);boolean res ValidCronUtil.isValidCronExpression(exp);if (!res) GlobalException.cast(参数有误);entity.setCron(exp);boolean result quartzUtil.addJob(entity.getJobname(), QuartzGroupEnum.T1.getValue(), MyJob.class,entity.getStarttime(), entity.getEndtime(), entity.getCron(), jobDataMap, entity.getRoleid());return result ? Rs.success(添加成功) : Rs.error(添加失败);}PostMapping(/modify-job)ApiOperation(value 修改任务, notes 修改任务, httpMethod POST)public Rs modifyQuartz(Valid RequestBody UpdateJobParam entity) {JobDataMap jobDataMap new JobDataMap();// false || false || trueif (entity.getMinute() ! null || entity.getHour() ! null || entity.getWeekDays() ! null) {String exp CronUtil.createCronExpression(2, entity.getMinute(), entity.getHour(), null, entity.getWeekDays(), null);boolean res ValidCronUtil.isValidCronExpression(exp);if (!res) GlobalException.cast(参数有误);entity.setCron(exp);jobDataMap.put(minute, entity.getMinute());jobDataMap.put(hour, entity.getHour());jobDataMap.put(weekDays, entity.getWeekDays());}if (entity.getRoleid() ! null) {jobDataMap.put(roleId, entity.getRoleid());}if (entity.getSendMessage() ! null) {jobDataMap.put(megContent, entity.getSendMessage());}if (entity.getDayType() ! null) {jobDataMap.put(dayType, entity.getDayType() null ? null : 1);}boolean result quartzUtil.modifyJobTime(entity.getJobname(), QuartzGroupEnum.T1.getValue(),entity.getStarttime(), entity.getEndtime(), entity.getCron(), entity.getId(), jobDataMap, entity.getRoleid());return result ? Rs.success(修改成功) : Rs.success(修改失败);}PostMapping(/cancel-job)ApiOperation(value 停止任务, notes 停止任务, httpMethod POST)public Rs cancelTimeQuartz(RequestBody QuartzEntity entity) {boolean result quartzUtil.cancelJob(entity.getJobname(), QuartzGroupEnum.T1.getValue());return result ? Rs.success(操作成功) : Rs.success(操作失败);}GetMapping(/get-all-jobs)ApiOperation(value 查询正在执行的任务, notes 查询正在执行的任务, httpMethod GET)public Rs getAllJobs() throws SchedulerException {return Rs.success(quartzUtil.getAllJobs());}GetMapping(/query-all-job)ApiOperation(value 查询所有创建的任务, notes 查询所有创建的任务, httpMethod GET)public Rs getAllJob() {return Rs.success(quartzWebService.queryJobAll());}private JobDataMap getJobDataMap(CreateJobParam entity) {JobDataMap jobDataMap new JobDataMap();jobDataMap.put(megContent, entity.getSendMessage());jobDataMap.put(roleId, entity.getRoleid());jobDataMap.put(dayType, entity.getDayType() null ? null : 1);jobDataMap.put(minute, entity.getMinute());jobDataMap.put(hour, entity.getHour());jobDataMap.put(weekDays, entity.getWeekDays());return jobDataMap;}
}Application启动类配置
/*** author Laity*/
MapperScan(com.laity.control_core.dao)
ComponentScan({com.laity.*})
EnableGlobalMethodSecurity(securedEnabled true, prePostEnabled true)
SpringBootApplication() // exclude {SecurityAutoConfiguration.class, SecurityFilterAutoConfiguration.class}
public class ControlApplication implements ApplicationRunner {Resourceprivate QuartzUtil quartzUtil;public static void main(String[] args) {SpringApplication.run(ControlApplication.class, args);}Overridepublic void run(ApplicationArguments args) throws Exception {quartzUtil.recoveryAllJob();}
}
MyJob定时业务
/*** author: Laity* Project: JavaLaity*/
Component(MysqlJob)
public class MysqlJob implements Job {protected final Logger logger LoggerFactory.getLogger(this.getClass());Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {JobKey key context.getJobDetail().getKey();JobDataMap jobDataMap context.getJobDetail().getJobDataMap();System.out.println(key.getName());String megContent (String) context.getTrigger().getJobDataMap().get(megContent);Integer roleId (Integer) context.getTrigger().getJobDataMap().get(roleId);Integer dayType (Integer) context.getTrigger().getJobDataMap().get(dayType);// 需要使用ServiceBean ARR arr (ARR) SpringContextJobUtil.getBean(arrWebService);……}SchedulerListener监听器
/*** author: Laity* Project: JavaLaity* Description: 全局监听器 - 接收所有的Trigger/Job的事件通知*/
public class MyJobListener implements SchedulerListener {Overridepublic void jobScheduled(Trigger trigger) {// 用于部署JobDetail时调用String jobName trigger.getJobKey().getName();System.out.println(用于部署JobDetail时调用 jobName);}Overridepublic void jobUnscheduled(TriggerKey triggerKey) {// 用于卸载JobDetail时调用System.out.println(triggerKey 完成卸载);}Overridepublic void triggerFinalized(Trigger trigger) {// 当endTime到了就会执行System.out.println(触发器被移除 trigger.getJobKey().getName());QuartzWebService quartzService (QuartzWebService) SpringContextJobUtil.getBean(quartzService);quartzService.modifyTaskStatus(trigger.getJobKey().getName(), 2);}Overridepublic void triggerPaused(TriggerKey triggerKey) {System.out.println(triggerKey 正在被暂停);}Overridepublic void triggersPaused(String s) {// s triggerGroupSystem.out.println(触发器组 s 正在被暂停);}Overridepublic void triggerResumed(TriggerKey triggerKey) {System.out.println(triggerKey 正在从暂停中恢复);}Overridepublic void triggersResumed(String s) {System.out.println(触发器组 s 正在从暂停中恢复);}Overridepublic void jobAdded(JobDetail jobDetail) {System.out.println(jobDetail.getKey() 已添加工作任务);}Overridepublic void jobDeleted(JobKey jobKey) {System.out.println(jobKey 已删除该工作任务);}Overridepublic void jobPaused(JobKey jobKey) {System.out.println(jobKey 工作任务正在被暂停);}Overridepublic void jobsPaused(String s) {System.out.println(工作任务组 s ,正在被暂停);}Overridepublic void jobResumed(JobKey jobKey) {System.out.println(jobKey jobKey正在从暂停中恢复);}Overridepublic void jobsResumed(String s) {System.out.println(工作任务组 s 正在从暂停中恢复);}Overridepublic void schedulerError(String s, SchedulerException e) {}Overridepublic void schedulerInStandbyMode() {}Overridepublic void schedulerStarted() {}Overridepublic void schedulerStarting() {System.out.println(开启监听);}Overridepublic void schedulerShutdown() {}Overridepublic void schedulerShuttingdown() {}Overridepublic void schedulingDataCleared() {}
}监听器使用 scheduler.scheduleJob(jobDetail, trigger);scheduler.getListenerManager().addSchedulerListener(new MyJobListener()); // 使用监听器封装接收前端Param
/*** author: Laity* Project: JavaLaity*/
Data
ApiModel(value 创建定时任务)
Accessors(chain true)
public class CreateJobParam {ApiModelProperty(value 任务名称)NotBlank(message 任务名称不能为空)private String jobname;ApiModelProperty(value 开始时间)private Date starttime;ApiModelProperty(value 结束时间)private Date endtime;// IgnoreApiModelProperty(value cron表达式)private String cron;ApiModelProperty(value 角色id)NotNull(message 角色ID不能为空)private Integer roleid;ApiModelProperty(value 消息内容)NotBlank(message 消息内容不能为空)private String sendMessage;ApiModelProperty(value 因为有的消息是发给昨日的某人所以设立此标识符正常的不用传值非正常1)private Integer dayType;ApiModelProperty(value 指定分钟 0-60)Max(60)Min(0)private Integer minute;Max(24)Min(0)ApiModelProperty(value 指定小时 0-24)private Integer hour;ApiModelProperty(value 星期列表: 1/星期天、2/星期一、3/...、7/星期六)private ListInteger weekDays;
}测试 说明 可根据自己的需求自行配置其余配置多线程、Reids缓存、MySQL、Quartz其余配置等 解决问题
修改Quartz中的JobDetailMap数据 因为我在JobDetailMap中放入了一些数据但是修改之后数据不发生变化 解决思路
最早写法是 // addjob中存jobDetailJobDetail jobDetail JobBuilder.newJob(jobClass).withIdentity(name, group).setJobData(jobDataMap).build();TriggerBuilderTrigger triggerBuilder newTrigger();更改后写法:
// 在构建Trigger实例时使用.usingJobData()方法实现TriggerBuilderTrigger triggerBuilder newTrigger();triggerBuilder.withIdentity(name, group);triggerBuilder.startAt(toStartDate(startTime));triggerBuilder.endAt(toEndDate(endTime));triggerBuilder.usingJobData(jobDataMap); // usingJobData传入jobDataMap其中出现的问题停止服务查询配置不一致
存数据库最初写法
// getAllJobs
entity.setJobDataMapJson(JSONUtil.toJsonStr(jobDetail.getJobDataMap()));现在写法:
// oldTrigger需要自己构建
entity.setJobdatamapjson(JSONUtil.toJsonStr(oldTrigger.getJobDataMap()));那么任务job的数据呢
最早的写法获取jobDataMap数据
String megContent (String) context.getJobDetail().getJobDataMap().get(megContent);
Integer roleId (Integer) context.getJobDetail().getJobDataMap().get(roleId);
Integer dayType (Integer) context.getJobDetail().getJobDataMap().get(dayType);期间也断点调试使用过其它数据获取方式
String megContent1 (String) jobDataMap.get(megContent);
Integer roleId1 (Integer) jobDataMap.get(roleId);
Integer dayType1 (Integer) jobDataMap.get(dayType);最终实现写法数据不论是临时修改还是怎么都可以实时更新
String megContent (String) context.getTrigger().getJobDataMap().get(megContent);
Integer roleId (Integer) context.getTrigger().getJobDataMap().get(roleId);
Integer dayType (Integer) context.getTrigger().getJobDataMap().get(dayType);昨日之深渊今日之浅谈我是Laity正在前行的Laity。