Quartz 之 scheduler 類的方法 【實現一個 quartz 管理類】
阿新 • • 發佈:2019-02-08
pause : 暫停一個觸發器。如果是持久化的 quartz,此觸發器的狀態會被寫到庫中,哪怕是重啟應用後,
也不會觸發,因為狀態是持久化的。若更新 quartz 配置檔案中的該觸發器的屬性,如 cron 表示式,則記憶體和資料庫中已持久化的資料都不會被更新。
resume : 重置一個觸發器的狀態為執行狀態,下次可排程。對一個不處於 pause 狀態的觸發器呼叫此方法無效果。此方法會改變觸發器的持久化狀態。
remove : 刪除一個觸發器(若是 cron 觸發器,則它關聯的 job 也會被刪除),此處,刪除的含義是,記憶體中刪除,若是持久化 quartz,則庫中的 trigger 和 job 也會被刪除。
重啟應用後,若原來的配置檔案不變更,則被刪除的 trigger 和 job 會被加回來,並且處於可觸發的狀態。
以下是完整的管理類。
package org.summer.spi.quartz; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.summer.exception.spe.SummerException; import org.summer.spi.spe.JobTriggerManageService; public class JobTriggerManagerServiceImpl implements JobTriggerManageService { private Scheduler scheduler; private final Logger logger = LoggerFactory.getLogger(this.getClass()); public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } public JobTriggerManagerServiceImpl() { // TODO Auto-generated constructor stub } @Override public List> getQrtzTriggers() { try { String[] triggerGroupNames = scheduler.getTriggerGroupNames(); List> triggersInfo = new ArrayList(); String[] triggerNames = null; Trigger trigger = null; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(int i=0;i curInfo = new HashMap<>(); trigger = scheduler.getTrigger(triggerNames[j],triggerGroupNames[i]); if(trigger instanceof CronTrigger) { curInfo.put("cron", ((CronTrigger)trigger).getCronExpression()); } else { curInfo.put("cron","非 cron 觸發器"); } curInfo.put("group", trigger.getGroup()); curInfo.put("name", trigger.getName()); curInfo.put("status", scheduler.getTriggerState(trigger.getName(), trigger.getGroup())); curInfo.put("lastTriggerTime", sdf.format(trigger.getPreviousFireTime())); curInfo.put("nextTriggerTime", sdf.format(trigger.getNextFireTime())); curInfo.put("startTriggerTime", sdf.format(trigger.getStartTime())); curInfo.put("endTriggerTime", null != trigger.getEndTime() ? sdf.format(trigger.getEndTime()) : ""); triggersInfo.add(curInfo); } } return triggersInfo; } catch(Exception e) { throw new SummerException(e); } } @Override public void pauseTrigger(String triggerName, String group) { try { scheduler.pauseTrigger(triggerName, group); } catch (SchedulerException e) { throw new SummerException(e); } } @Override public void resumeTrigger(String triggerName, String group) { try { scheduler.resumeTrigger(triggerName, group); } catch (SchedulerException e) { throw new SummerException(e); } } @Override public void removeTrigger(String triggerName, String group){ try { scheduler.unscheduleJob(triggerName, group); } catch (SchedulerException e) { throw new SummerException(e); } } @Override public String triggerRelativeJobsRightNow(String triggerName, String group){ StringBuilder sb = new StringBuilder(); try { String[] jobGroups = scheduler.getJobGroupNames(); for(String curJobGroup : jobGroups) { String[] jobs = scheduler.getJobNames(curJobGroup); for(String job : jobs) { try { Trigger[] triggers = scheduler.getTriggersOfJob(job, curJobGroup); if(null != triggers && 1 == triggers.length && triggers[0].getName().equals(triggerName) && triggers[0].getGroup().equals(group)) { scheduler.triggerJobWithVolatileTrigger(job, curJobGroup); sb.append(curJobGroup + "." + job).append(" | "); } } catch(Exception innerEx) { logger.warn("觸發 job " + curJobGroup + "." + job + " 失敗.",innerEx); } } } } catch (SchedulerException e) { throw new SummerException(e); } if(0 != sb.length()) sb.delete(sb.length() - " | ".length(), sb.length()); return sb.toString(); } }
以上管理類只適用於 1.8 及以下版本的 Quartz,對於新版本,Scheduler 不再提供一些方法,不再適用。下面給出適用於新版本的觸發器管理類
package ---.---.---.service.impl; /** * 和老版本 Quartz 的觸發器管理類 JobTriggerManagerServiceImpl.java 的實現不一樣,新版本的 Quartz 減少了一些介面,加入了新介面。 * 如不再提供 triggerJobWithVolatileTrigger 方法。“立即觸發功能” 可以使用 java 反射做。 * */ import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.quartz.CronTrigger; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerKey; import org.quartz.impl.matchers.GroupMatcher; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.webank.mbp.ccsm.service.JobTriggerManageService; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class JobTriggerManagerServiceImpl implements JobTriggerManageService,ApplicationContextAware { @Autowired SchedulerFactoryBean schedulerFactoryBean; private static ApplicationContext applicationContext; // Spring應用上下文環境 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public JobTriggerManagerServiceImpl() { // TODO Auto-generated constructor stub } @Override public List> getQrtzTriggers() throws SchedulerException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Scheduler scheduler = schedulerFactoryBean.getScheduler(); GroupMatcher matcher = GroupMatcher.anyTriggerGroup(); Set triggerKeys = scheduler.getTriggerKeys(matcher); List triggerGroupNames = scheduler.getTriggerGroupNames(); List> triggersInfo = new ArrayList(); for(TriggerKey key : triggerKeys) { Trigger trigger = scheduler.getTrigger(key); Map curInfo = new HashMap<>(); if(trigger instanceof CronTrigger) { curInfo.put("cron", ((CronTrigger)trigger).getCronExpression()); } else { curInfo.put("cron","非 cron 觸發器"); } curInfo.put("group",key.getGroup()); curInfo.put("name", key.getName()); curInfo.put("status", scheduler.getTriggerState(key)); curInfo.put("lastTriggerTime", null != trigger.getPreviousFireTime() ? sdf.format(trigger.getPreviousFireTime()) : ""); curInfo.put("nextTriggerTime", null != trigger.getNextFireTime() ? sdf.format(trigger.getNextFireTime()) : ""); curInfo.put("startTriggerTime", null != trigger.getStartTime() ? sdf.format(trigger.getStartTime()) : ""); curInfo.put("endTriggerTime", null != trigger.getEndTime() ? sdf.format(trigger.getEndTime()) : ""); triggersInfo.add(curInfo); } return triggersInfo; } @Override public void pauseTrigger(String triggerName, String group) throws SchedulerException{ schedulerFactoryBean.getScheduler().pauseTrigger(new TriggerKey(triggerName, group)); } @Override public void resumeTrigger(String triggerName, String group) throws SchedulerException{ schedulerFactoryBean.getScheduler().resumeTrigger(new TriggerKey(triggerName, group)); } @Override public void removeTrigger(String triggerName, String group) throws SchedulerException{ Set keys = getStrictRelativeJob(triggerName, group); schedulerFactoryBean.getScheduler().unscheduleJob(new TriggerKey(triggerName, group)); List keyList = new ArrayList<>(); keyList.addAll(keys); schedulerFactoryBean.getScheduler().deleteJobs(keyList); } /* * 獲得一個 trigger 強關聯的 job. 即 job 只與這一個 trigger 相關聯 */ private Set getStrictRelativeJob(String triggerName, String group) throws SchedulerException { Set rets = new HashSet<>(); Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey target = new TriggerKey(triggerName, group); Set jobKeys = scheduler.getJobKeys(GroupMatcher.anyJobGroup());//GroupMatcher.jobGroupEquals(group) for(JobKey key : jobKeys) { List triggers = (List) scheduler.getTriggersOfJob(key); if(null != triggers && 1 == triggers.size() && triggers.get(0).getKey().equals(target)) { rets.add(key); } } return rets; } private void triggerRightNow(JobKey jobKey) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); Class jobClass = scheduler.getJobDetail(jobKey).getJobClass(); Job jobObj = (Job)applicationContext.getBean(jobClass); try { Method targetMethod = jobClass.getDeclaredMethod("executeInternal", new Class[] {JobExecutionContext.class}); targetMethod.setAccessible(true); targetMethod.invoke(jobObj, new Object[]{null}); targetMethod.setAccessible(false); } catch(Exception e) { throw new SchedulerException(e); } } @Autowired ObjectMapper json; @Override public String triggerRelativeJobsRightNow(String triggerName, String group)throws SchedulerException{ StringBuilder sb = new StringBuilder(); Scheduler scheduler = schedulerFactoryBean.getScheduler(); Trigger trigger = scheduler.getTrigger(new TriggerKey(triggerName, group)); Set jobKeys = getStrictRelativeJob(triggerName, group); for(JobKey key : jobKeys) { triggerRightNow(key); sb.append(key.getGroup() + "." + key.getName()).append(" | "); } if(0 != sb.length()) sb.delete(sb.length() - " | ".length(), sb.length()); return sb.toString(); } }