1、quartz.properties配置
org.quartz.scheduler.instanceName = MyScheduler org.quartz.threadPool.threadCount = 20 org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
2、创建一个配置类,用于QuartZ的启动配置-QuartZConfig:
import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @ClassName: QuartZConfig * @Description: * @Author jm * @Date 2022/6/11 * @Version 1.0 */ @Configuration public class QuartZConfig { /** * quartz 启动配置 */ @Bean public SchedulerFactory quartz() throws SchedulerException { // Creating scheduler factory and scheduler SchedulerFactory factory = new StdSchedulerFactory("quartz.properties"); Scheduler scheduler = factory.getScheduler(); scheduler.start(); return factory; } }
3、QuartzManage 定时任务工具类
import lombok.extern.slf4j.Slf4j; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; /** * quartz定时任务工具类,对任务进行管理(创建、修改、删除、暂停) * * @author lyf */ @Slf4j public class QuartzManage { private static final SchedulerFactory SCHEDULER_FACTORY = new StdSchedulerFactory(); /** * 启动调度任务 * * @param jobDetail 执行任务 * @param trigger 触发器 */ private static void startScheduler(JobDetail jobDetail, Trigger trigger) { try { // 获取调度任务实例 Scheduler scheduler = SCHEDULER_FACTORY.getScheduler(); // 绑定触发器和调度任务 scheduler.scheduleJob(jobDetail, trigger); // 启动 scheduler.start(); } catch (SchedulerException e) { String msg = "启动调度任务失败"; log.error(msg, e); //throw new Exception(msg); } } /** * 任务执行实例 * * @param jobName 任务名称 * @param jobGroupName 任务分组名 * @param jobDataMap 执行参数 * @param jobClass 执行类-实现了{@code org.quartz.Job}接口的类 * @return {@link JobDetail} */ private static JobDetail getJobDetail(String jobName, String jobGroupName, JobDataMap jobDataMap, Class<? extends Job> jobClass) { // 获取任务执行类的实例 JobBuilder jobBuilder = JobBuilder.newJob(jobClass); // 添加任务名,任务组 jobBuilder.withIdentity(jobName, jobGroupName); // 添加任务执行的参数 if (jobDataMap != null && jobDataMap.size() > 0) { jobBuilder.setJobData(jobDataMap); } // 获取job执行实例 return jobBuilder.build(); } /** * cron触发器 * * @param triggerName 触发器名 * @param triggerGroupName 触发器分组名 * @param cron 定时策略 * @return {@link CronTrigger} */ private static CronTrigger getCronTrigger(String triggerName, String triggerGroupName, String cron) { // 触发器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); // 触发器时间设定 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron)); // 从当前时间判断触发 triggerBuilder.startNow(); // 创建Trigger对象 return (CronTrigger) triggerBuilder.build(); } /** * 一次任务触发器 * * @param triggerName 触发器名 * @param triggerGroupName 触发器分组名 * @return {@link SimpleTrigger} */ private static SimpleTrigger getOnceTrigger(String triggerName, String triggerGroupName) { // 触发器 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); // 触发器名,触发器组 triggerBuilder.withIdentity(triggerName, triggerGroupName); // 5秒后立即执行,重复次数设为0,表示只执行一次 triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).withRepeatCount(0)); // 从当前时间判断触发 triggerBuilder.startNow(); // 创建Trigger对象 return (SimpleTrigger) triggerBuilder.build(); } /** * 创建添加定时任务 */ public static void addCronJob(QuartzJob quartzJob,String cron) throws Exception { String triggerName = "trigger"+quartzJob.getJobName(); String triggerState = getTriggerState(triggerName, quartzJob.getJobGroup()); if (Trigger.TriggerState.NONE.name().equals(triggerState)) { Class cls = Class.forName(quartzJob.getJobClassName()) ; cls.newInstance(); //构建job信息 JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(quartzJob.getJobName(), quartzJob.getJobGroup()) .withDescription(quartzJob.getDescription()).build(); //jobDetail.getJobDataMap().put("jobMethodName", quartzJob.getJobMethodName()); // 触发时间点 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron); Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, quartzJob.getJobGroup()) .startNow().withSchedule(cronScheduleBuilder).build(); startScheduler(jobDetail, trigger); } } /** * 移除定时任务 */ public static void removeJob(QuartzJob quartzJob) { // 定时任务不存在就不处理 String triggerName = "trigger"+quartzJob.getJobName(); String triggerState = getTriggerState(triggerName, quartzJob.getJobGroup()); if (Trigger.TriggerState.NONE.name().equals(triggerState)) { return; } try { Scheduler scheduler = SCHEDULER_FACTORY.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, quartzJob.getJobGroup()); // 停止触发器 scheduler.pauseTrigger(triggerKey); // 移除触发器 scheduler.unscheduleJob(triggerKey); JobKey jobKey = JobKey.jobKey(quartzJob.getJobName(), quartzJob.getJobGroup()); // 停止任务 scheduler.interrupt(jobKey); // 删除任务 scheduler.deleteJob(jobKey); } catch (SchedulerException e) { String msg = "停止定时任务失败"; log.error(msg, e); // throw new MyMessageException(GlobalStatusEnum.QUARTZ_ERROR, msg); } } /** * 获取触发器状态 * * @param triggerName 触发器名 * @param triggerGroupName 触发器分组名 * @return 状态 * NONE: 不存在 * NORMAL: 正常 * PAUSED: 暂停 * COMPLETE:完成 * ERROR : 错误 * BLOCKED : 阻塞 */ public static String getTriggerState(String triggerName, String triggerGroupName) { TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); try { Scheduler scheduler = SCHEDULER_FACTORY.getScheduler(); Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey); return triggerState.name(); } catch (SchedulerException e) { String msg = "获取触发器状态失败"; log.error(msg, e); //throw new MyMessageException(GlobalStatusEnum.QUARTZ_ERROR, msg); } return "获取触发器状态失败"; } }
4、创建需要执行的Job类
import org.quartz.*; import org.springframework.scheduling.annotation.Schedules; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 实现序列化接口、防止重启应用出现quartz Couldn't retrieve job because a required class was not found 的问题 * Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行,一个新的 Job 实例会被创建。 * 其中暗含的意思就是你的 Job 不必担心线程安全性,因为同一时刻仅有一个线程去执行给定 Job 类的实例,甚至是并发执行同一 Job 也是如此。 * @DisallowConcurrentExecution 保证上一个任务执行完后,再去执行下一个任务,这里的任务是同一个任务 */ @DisallowConcurrentExecution public class DemoJob implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) { System.out.println("测试方法1"); } }
5、编辑QuartzJob实体类
import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; import java.io.Serializable; import java.util.Date; @Data public class QuartzJob implements Serializable { private long id; private String jobName; private String jobGroup; private String jobClassName; private String jobMethodName; private String cronExpression; private String categoryId; private String triggerState; private String triggerName; private String transLogLevel; private String description; @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date createTime; @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") private Date updateTime; @Override public String toString() { return "QuartzJob{" + "id=" + id + ", jobName='" + jobName + '\'' + ", jobGroup='" + jobGroup + '\'' + ", jobClassName='" + jobClassName + '\'' + ", jobMethodName='" + jobMethodName + '\'' + ", cronExpression='" + cronExpression + '\'' + ", categoryId='" + categoryId + '\'' + ", triggerState='" + triggerState + '\'' + ", triggerName='" + triggerName + '\'' + ", transLogLevel='" + transLogLevel + '\'' + ", description='" + description + '\'' + ", createTime=" + createTime + ", updateTime=" + updateTime + '}'; } }
6、添加JObJobWController
import com.itstyle.quartz.entity.*; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/job") public class JobWController { @PostMapping("/startJob") public Object startJob() throws Exception{ QuartzJob quartzJob = new QuartzJob(); quartzJob.setJobName("test01"); quartzJob.setJobGroup("ChickenJob"); quartzJob.setDescription("测试任务"); quartzJob.setJobClassName("com.itstyle.quartz.job.ChickenJob"); quartzJob.setCronExpression("*/5 * * * * ?"); quartzJob.setJobMethodName("test1"); QuartzManage.addCronJob(quartzJob,quartzJob.getCronExpression()); return "成功"; } }