package cn.com.goldenwater.dcproj.task; import cn.com.goldenwater.dcproj.model.BisInspTaskScheduler; import cn.com.goldenwater.dcproj.param.BisInspTaskSchedulerParam; import cn.com.goldenwater.dcproj.service.BisInspTaskSchedulerService; import cn.com.goldenwater.dcproj.utils.TaskUtils; import org.apache.commons.lang3.StringUtils; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.util.List; import static org.quartz.CronExpression.isValidExpression; /** * @author lhc * @date 2020/10/12 9:10 */ @Component public class TaskInitService { private Logger log = LoggerFactory.getLogger(getClass()); @Autowired private BisInspTaskSchedulerService bisInspTaskSchedulerService; @Autowired private Scheduler scheduler; private final static String TASK_STATUS = "1"; /** * 初始化 */ @PostConstruct public void init() { if (scheduler == null) { log.error("初始化定时任务组件失败,Scheduler is null..."); return; } // 初始化基于cron时间配置的任务列表 try { // initCronJobs(scheduler); } catch (Exception e) { log.error("init cron tasks error," + e.getMessage(), e); } try { // log.info("The scheduler is starting..."); // scheduler.start(); // start the scheduler } catch (Exception e) { log.error("The scheduler start is error," + e.getMessage(), e); } } /** * 初始化任务(基于cron触发器) */ private void initCronJobs(Scheduler scheduler) throws Exception { BisInspTaskSchedulerParam bisInspTaskSchedulerParam = new BisInspTaskSchedulerParam(); bisInspTaskSchedulerParam.setTaskStatus(TASK_STATUS); Iterable jobList = bisInspTaskSchedulerService.findList(bisInspTaskSchedulerParam); if (jobList != null) { for (BisInspTaskScheduler job : jobList) { scheduleCronJob(job, scheduler); } } } /** * 安排任务(基于cron触发器) * * @param job * @param scheduler */ private void scheduleCronJob(BisInspTaskScheduler job, Scheduler scheduler) { if (job != null && StringUtils.isNotBlank(job.getTaskName()) && StringUtils.isNotBlank(job.getTaskClass()) && StringUtils.isNotBlank(job.getTaskSchedule()) && scheduler != null) { try { JobKey jobKey = TaskUtils.genCronJobKey(job); // 判断 key是否存在 已存在更新 job, 不存在新建 job if (!scheduler.checkExists(jobKey)) { // 创建新 job log.info("Add new cron job to scheduler, jobName = " + job.getTaskName()); this.newJobAndNewCronTrigger(job, scheduler, jobKey); } else { // 更新 job log.info("Update cron job to scheduler, jobName = " + job.getTaskName()); this.updateCronTriggerOfJob(job, scheduler, jobKey); } } catch (Exception e) { log.error("ScheduleCronJob is error," + e.getMessage(), e); } } else { log.error("Method scheduleCronJob arguments are invalid."); } } /** * 新建job和trigger到scheduler(基于cron触发器) * * @param job * @param scheduler * @param jobKey * @throws SchedulerException * @throws ClassNotFoundException */ @SuppressWarnings({"rawtypes", "unchecked"}) private void newJobAndNewCronTrigger(BisInspTaskScheduler job, Scheduler scheduler, JobKey jobKey) throws SchedulerException, ClassNotFoundException { TriggerKey triggerKey = TaskUtils.genCronTriggerKey(job); String cronExpr = job.getTaskSchedule(); if (!isValidExpression(cronExpr)) { return; } // get a Class object by string class name of job; Class jobClass = Class.forName(job.getTaskClass().trim()); JobDetail jobDetail = JobBuilder.newJob(jobClass) .withIdentity(jobKey) .withDescription(job.getTaskDesc()) .usingJobData("param", job.getTaskParams()) .build(); CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).forJob(jobKey) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpr).withMisfireHandlingInstructionFireAndProceed()) .build(); scheduler.scheduleJob(jobDetail, trigger); } /** * 更新job的trigger(基于cron触发器) * * @param job * @param scheduler * @param jobKey * @throws SchedulerException */ private void updateCronTriggerOfJob(BisInspTaskScheduler job, Scheduler scheduler, JobKey jobKey) throws SchedulerException { TriggerKey triggerKey = TaskUtils.genCronTriggerKey(job); String cronExpr = job.getTaskSchedule().trim(); List triggers = scheduler.getTriggersOfJob(jobKey); for (int i = 0; triggers != null && i < triggers.size(); i++) { Trigger trigger = triggers.get(i); TriggerKey curTriggerKey = trigger.getKey(); if (TaskUtils.isTriggerKeyEqual(triggerKey, curTriggerKey)) { if (trigger instanceof CronTrigger && cronExpr.equalsIgnoreCase(((CronTrigger) trigger).getCronExpression())) { // Don't need to do anything. } else { if (isValidExpression(job.getTaskSchedule())) { // Cron expression is valid, build a new trigger and // replace the old one. CronTrigger newTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).forJob(jobKey) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpr) .withMisfireHandlingInstructionDoNothing()) .build(); scheduler.rescheduleJob(curTriggerKey, newTrigger); } } } else { // different trigger key ,The trigger key is illegal, unschedule // this trigger scheduler.unscheduleJob(curTriggerKey); } } } }