/* * Copyright (c) 2018-2025, hnqz All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the pig4cloud.com developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: hnqz */ package net.yyc.quartz.util; import lombok.extern.slf4j.Slf4j; import net.yyc.quartz.config.QuartzFactory; import net.yyc.quartz.entity.SysJob; import org.quartz.*; import org.springframework.stereotype.Component; import static net.yyc.quartz.constants.QuartzEnum.*; /** * 定时任务的工具类 * * @author 郑健楠 */ @Slf4j @Component public class TaskUtil { /** * 获取定时任务的唯一key */ public static JobKey getJobKey(SysJob sysjob) { return JobKey.jobKey(sysjob.getJobName(), sysjob.getJobGroup()); } /** * 获取定时任务触发器cron的唯一key */ public static TriggerKey getTriggerKey(SysJob sysjob) { return TriggerKey.triggerKey(sysjob.getJobName(), sysjob.getJobGroup()); } /** * 添加或更新定时任务 */ public void addOrUpdateJob(SysJob sysjob, Scheduler scheduler) { CronTrigger trigger = null; try { JobKey jobKey = getJobKey(sysjob); // 获得触发器 TriggerKey triggerKey = getTriggerKey(sysjob); trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 判断触发器是否存在(如果存在说明之前运行过但是在当前被禁用了,如果不存在说明一次都没运行过) if (trigger == null) { JobDetail jobDetail = JobBuilder.newJob(QuartzFactory.class).withIdentity(jobKey).build(); jobDetail.getJobDataMap().put(SCHEDULE_JOB_KEY.getType(), sysjob); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysjob.getCronExpression()); cronScheduleBuilder = this.handleCronScheduleMisfirePolicy(sysjob, cronScheduleBuilder); trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); } else { CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(sysjob.getCronExpression()); cronScheduleBuilder = this.handleCronScheduleMisfirePolicy(sysjob, cronScheduleBuilder); trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); trigger.getJobDataMap().put(SCHEDULE_JOB_KEY.getType(), sysjob); scheduler.rescheduleJob(triggerKey, trigger); } // 如任务状态为暂停 if (sysjob.getJobStatus().equals(JOB_STATUS_NOT_RUNNING.getType())) { this.pauseJob(sysjob, scheduler); } } catch (SchedulerException e) { log.error("添加或更新定时任务,失败信息:{}", e.getMessage()); } } /** * 立即执行一次任务 */ public static boolean runOnce(Scheduler scheduler, SysJob sysJob) { try { // 参数 JobDataMap dataMap = new JobDataMap(); dataMap.put(SCHEDULE_JOB_KEY.getType(), sysJob); scheduler.triggerJob(getJobKey(sysJob), dataMap); } catch (SchedulerException e) { log.error("立刻执行定时任务,失败信息:{}", e.getMessage()); return false; } return true; } /** * 暂停定时任务 */ public void pauseJob(SysJob sysjob, Scheduler scheduler) { try { if (scheduler != null) { scheduler.pauseJob(getJobKey(sysjob)); } } catch (SchedulerException e) { log.error("暂停任务失败,失败信息:{}", e.getMessage()); } } /** * 恢复定时任务 */ public void resumeJob(SysJob sysjob, Scheduler scheduler) { if (scheduler == null) { return; } try { TriggerKey triggerKey = getTriggerKey(sysjob); Trigger trigger = scheduler.getTrigger(triggerKey); if (trigger == null) { addOrUpdateJob(sysjob, scheduler); } else { scheduler.resumeJob(getJobKey(sysjob)); } } catch (SchedulerException e) { log.error("恢复任务失败,失败信息:{}", e.getMessage()); } } /** * 移除定时任务 */ public void removeJob(SysJob sysjob, Scheduler scheduler) { try { if (scheduler != null) { // 停止触发器 scheduler.pauseTrigger(getTriggerKey(sysjob)); // 移除触发器 scheduler.unscheduleJob(getTriggerKey(sysjob)); // 删除任务 scheduler.deleteJob(getJobKey(sysjob)); } } catch (Exception e) { log.error("移除定时任务失败,失败信息:{}", e.getMessage()); } } /** * 启动所有运行定时任务 */ public void startJobs(Scheduler scheduler) { try { if (scheduler != null) { scheduler.resumeAll(); } } catch (SchedulerException e) { log.error("启动所有运行定时任务失败,失败信息:{}", e.getMessage()); } } /** * 停止所有运行定时任务 */ public void pauseJobs(Scheduler scheduler) { try { if (scheduler != null) { scheduler.pauseAll(); } } catch (Exception e) { log.error("暂停所有运行定时任务失败,失败信息:{}", e.getMessage()); } } /** * 获取错失执行策略方法 */ private CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob sysJob, CronScheduleBuilder cronScheduleBuilder) { if (MISFIRE_DEFAULT.getType().equals(sysJob.getMisfirePolicy())) { return cronScheduleBuilder; } else if (MISFIRE_IGNORE_MISFIRES.getType().equals(sysJob.getMisfirePolicy())) { //return cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); //调度任务无需补救 } else if (MISFIRE_FIRE_AND_PROCEED.getType().equals(sysJob.getMisfirePolicy())) { return cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); } else if (MISFIRE_DO_NOTHING.getType().equals(sysJob.getMisfirePolicy())) { return cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); } return cronScheduleBuilder; } /** * 判断cron表达式是否正确 */ public boolean isValidCron(String cronExpression) { return CronExpression.isValidExpression(cronExpression); } }