1.定義job導出類
1 public class MyQuartzJob implements Job { 2 private static Logger logger = LoggerFactory.getLogger(MyQuartzJob.class); 3 4 @Override 5 public void execute(JobExecutionContext context) throws JobExecutionException { 6 // TODO Auto-generated method stub 7 System.out.println("任務成功運行,時間為:===" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); 8 // JobDataMap jdm = context.getMergedJobDataMap(); 9 10 JobDetailImpl jdi = (JobDetailImpl) context.getJobDetail(); 11 12 JobKey jk = jdi.getKey(); 13 14 String jobName = jk.getName(); 15 String jobGroup = jk.getGroup(); 16 17 Trigger trigger = context.getTrigger(); 18 TriggerKey triggerKey = trigger.getKey(); 19 20 String triggerName = triggerKey.getName(); 21 String triggerGroup = triggerKey.getGroup(); 22 23 if (jobName.equals("我的cron任務1")) { 24 try { 25 QuartzManager.modifyJobTime(triggerKey, "0 0/3 * * * ?"); 26 } catch (SchedulerException e) { 27 // TODO Auto-generated catch block 28 e.printStackTrace(); 29 } 30 } 31 System.out.println("當前執行的job是:" + jobName + ";job的組名是:" + jobGroup + ";trigger名稱是:" + triggerName 32 + ";trigger的組名是:" + triggerGroup + ";下次執行時間為:" 33 + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(context.getNextFireTime())); 34 System.out.println(); 35 // JobDetailImpl scheduleJob = (JobDetailImpl) 36 // context.getMergedJobDataMap().get("scheduleJob"); 37 // System.out.println("任務名稱 = [" + scheduleJob.getName() + "]"); 38 39 /* 40 *從jobDataMap中取得推送相關的額外信息; 41 * */ 42 JobDataMap dataMap = context.getMergedJobDataMap(); 43 // userId 44 String userId = (String) dataMap.get("userId"); 45 // 46 String messageTypes = (String) dataMap.get("messageTypes"); 47 48 //下邊的這里是項目的業務 就不貼出來了 49 // 根據用戶id查詢該用戶定義的 50 // PushAlarmService alarmService = SpringUtils.getBean(PushAlarmService.class); 51 // alarmService.selByUserId(Integer.valueOf(userId)); 52 53 } 54 }
2.定義一個定時器的管理類:專門負責定時器的新增、修改、刪除、啟動、結束等。
1 import org.quartz.CronScheduleBuilder; 2 import org.quartz.CronTrigger; 3 import org.quartz.JobBuilder; 4 import org.quartz.JobDataMap; 5 import org.quartz.JobDetail; 6 import org.quartz.JobKey; 7 import org.quartz.Scheduler; 8 import org.quartz.SchedulerException; 9 import org.quartz.SimpleScheduleBuilder; 10 import org.quartz.SimpleTrigger; 11 import org.quartz.Trigger; 12 import org.quartz.TriggerBuilder; 13 import org.quartz.TriggerKey; 14 import org.quartz.impl.StdSchedulerFactory; 15 16 public class QuartzManager { 17 // private static final String JOB_GROUP_NAME = "SDJK_APP_JOBGROUP_NAME"; 18 /// private static String TRIGGER_GROUP_NAME = "SDJK_APP_TRIGGERGROUP_NAME"; 19 public static StdSchedulerFactory sf = new StdSchedulerFactory(); 20 // public static StdScheduler ss = (StdScheduler) SpringUtils.getBean("schedulerFactoryBean"); 21 22 /** 23 * 24 * @Title: 25 * @Description: 創建SimpleTrigger定時器,startnow,run forever 26 * 27 * @param jobKey 28 * @param triggerKey 29 * @param cls 30 * @param repeatIntevalTime 31 * @throws SchedulerException 32 */ 33 public static void addJob(JobKey jobKey, TriggerKey triggerKey, Class<? extends Job> cls, int repeatIntevalTime, 34 JobDataMap jobDataMap) throws SchedulerException { 35 36 Scheduler sched = sf.getScheduler(); 37 38 JobDetail jd = JobBuilder.newJob(cls).withIdentity(jobKey).setJobData(jobDataMap).build();// jobDetail 39 40 SimpleTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey) 41 .withSchedule( 42 SimpleScheduleBuilder.simpleSchedule().withIntervalInHours(repeatIntevalTime).repeatForever()) 43 .startNow().build();// triggerkey用來標識trigger身份 44 45 sched.scheduleJob(jd, trigger);// 設置調度器 46 47 try { 48 49 if (!sched.isShutdown()) { 50 sched.start(); 51 } 52 53 } catch (SchedulerException e) { 54 // TODO Auto-generated catch block 55 e.printStackTrace(); 56 } 57 } 58 59 /** 60 * 61 * @Title: 62 * @Description: 添加cronTrigger的定時器 63 * 64 * @param jobKey 65 * @param triggerKey 66 * @param jobClass 67 * @param cron 68 * @param JobDataMap 69 * jobDataMap 70 */ 71 @SuppressWarnings({ "unchecked", "rawtypes" }) 72 public static void addJob(JobKey jobKey, TriggerKey triggerKey, Class jobClass, String cron, 73 JobDataMap jobDataMap) { 74 try { 75 // 任務名,任務組,任務執行類;可以將自己需要的額外信息添加到jobdatamap中。 76 JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobKey).setJobData(jobDataMap).build(); 77 78 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 觸發器 79 80 triggerBuilder.withIdentity(triggerKey);// 觸發器名,觸發器組 81 82 triggerBuilder.startNow();// 現在執行 83 84 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));// 觸發器執行規則 85 86 CronTrigger trigger = (CronTrigger) triggerBuilder.build();// 創建CronTrigger對象 87 88 Scheduler sched = sf.getScheduler();// 創建調度器 89 90 sched.scheduleJob(jobDetail, trigger);// 調度容器設置JobDetail和Trigger 91 92 if (!sched.isShutdown()) {// 啟動 93 sched.start(); 94 } 95 } catch (Exception e) { 96 throw new RuntimeException(e); 97 } 98 } 99 100 /** 101 * 102 * @Title: 103 * @Description: 修改cronTrigger定時器 104 * 105 * @param triggerKey 106 * trigger標識 107 * @param cron 108 * @throws SchedulerException 109 */ 110 public static void modifyJobTime(TriggerKey triggerKey, String cron) throws SchedulerException { 111 112 Scheduler sched = sf.getScheduler(); 113 114 try { 115 // TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName); 116 117 CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey); 118 119 if (trigger == null) { 120 return; 121 } 122 123 String oldTime = trigger.getCronExpression(); 124 125 if (!oldTime.equalsIgnoreCase(cron)) { 126 127 /** 方式一 :調用 rescheduleJob 開始 */ 128 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 觸發器 129 130 triggerBuilder.withIdentity(triggerKey);// 觸發器名,觸發器組 131 132 triggerBuilder.startNow();// 立即執行 133 134 triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));// 觸發器時間設定 135 136 trigger = (CronTrigger) triggerBuilder.build();// 創建Trigger對象 137 138 sched.rescheduleJob(triggerKey, trigger);// 修改一個任務的觸發時間 139 140 /** 方式一 :調用 rescheduleJob 結束 */ 141 142 /** 方式二:先刪除,然后在創建一個新的Job */ 143 // JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName)); 144 // Class<? extends Job> jobClass = jobDetail.getJobClass(); 145 // removeJob(jobName, jobGroupName, triggerName, triggerGroupName); 146 // addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 147 /** 方式二 :先刪除,然后在創建一個新的Job */ 148 } 149 } catch (Exception e) { 150 throw new RuntimeException(e); 151 } 152 } 153 154 /** 155 * 156 * @Title: 157 * @Description: 只修改simpleTrigger觸發器的觸發時間,不更改trigger的triggerKey 158 * 159 * @param triggerKey 160 * trigger標識 161 * @param repeatIntervalTime 162 * 重復間隔時長 163 * @throws SchedulerException 164 */ 165 public static void modifyJobTime(TriggerKey triggerKey, int repeatIntervalTime) throws SchedulerException { 166 167 Scheduler sched = sf.getScheduler(); 168 169 try { 170 171 SimpleTrigger trigger = (SimpleTrigger) sched.getTrigger(triggerKey); 172 173 if (trigger == null) { 174 return; 175 } 176 177 long oldTime = trigger.getRepeatInterval(); 178 179 if (oldTime != repeatIntervalTime) { 180 181 /** 方式一 :調用 rescheduleJob 開始 */ 182 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();// 觸發器builder 183 184 triggerBuilder.withIdentity(triggerKey);// 觸發器名,觸發器組 185 186 triggerBuilder.withSchedule(SimpleScheduleBuilder.repeatHourlyForever(repeatIntervalTime));// 更新觸發器的重復間隔時間 187 188 triggerBuilder.startNow();// 立即執行 189 190 trigger = (SimpleTrigger) triggerBuilder.build();// 創建Trigger對象 191 192 sched.rescheduleJob(triggerKey, trigger);// 修改一個任務的觸發時間 193 194 /** 方式一 :調用 rescheduleJob 結束 */ 195 196 /** 方式二:先刪除,然后在創建一個新的Job */ 197 // JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName)); 198 // Class<? extends Job> jobClass = jobDetail.getJobClass(); 199 // removeJob(jobName, jobGroupName, triggerName, triggerGroupName); 200 // addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron); 201 /** 方式二 :先刪除,然后在創建一個新的Job */ 202 } 203 204 } catch (Exception e) { 205 throw new RuntimeException(e); 206 } 207 } 208 209 /** 210 * 211 * @Title: 212 * @Description: 根據job和trigger刪除任務 213 * 214 * @param jobKey 215 * @param triggerKey 216 */ 217 public static void removeJob(JobKey jobKey, TriggerKey triggerKey) { 218 219 try { 220 221 Scheduler sched = sf.getScheduler(); 222 223 sched.pauseTrigger(triggerKey);// 停止觸發器 224 225 sched.unscheduleJob(triggerKey);// 移除觸發器 226 227 sched.deleteJob(jobKey);// 刪除任務 228 229 } catch (Exception e) { 230 231 throw new RuntimeException(e); 232 233 } 234 } 235 236 /** 237 * @Description:啟動所有定時任務 238 */ 239 public static void startJobs(Scheduler sched) { 240 try { 241 sched.start(); 242 } catch (Exception e) { 243 throw new RuntimeException(e); 244 } 245 } 246 247 /** 248 * @Description:關閉所有定時任務 249 */ 250 public static void shutdownJobs(Scheduler sched) { 251 try { 252 if (!sched.isShutdown()) { 253 sched.shutdown(); 254 } 255 } catch (Exception e) { 256 throw new RuntimeException(e); 257 } 258 } 259 260 /** 261 * 262 * @Title: 263 * @Description: 新增或者修改 264 * 265 * @param jobKey 266 * @param triggerKey 267 * @param clz 268 * @param intervalTime 269 * @param jobDataMap 270 * @throws SchedulerException 271 */ 272 public static void addOrModify(JobKey jobKey, TriggerKey triggerKey, @SuppressWarnings("rawtypes") Class clz, 273 int intervalTime, JobDataMap jobDataMap) throws SchedulerException { 274 275 Scheduler sched = sf.getScheduler(); 276 277 if (sched.checkExists(jobKey)) {// 如果存在,則modify一下job和trigger 278 279 } 280 281 if (sched.checkExists(triggerKey)) {// modify修改trigger 282 283 modifyJobTime(triggerKey, intervalTime); 284 285 } else {// add新增 286 287 addJob(jobKey, triggerKey, clz, intervalTime, jobDataMap); 288 289 } 290 291 } 292 }
可以看到,每次創建job是都要使用一個實現了job接口的類,這個類就是我們自己實現的job導出類。
3.初始定時任務的初始化類。作用:項目啟動時,初始化自己定義的定時器。既然需要項目啟動時就加載所有的定時器,那么需要在spring容器加載時一起加載。
1 public class InitQuartzJob { 2 3 /** 4 * @throws SchedulerException 5 * @Description:服務啟動時,根據用戶定義的推送規則,初始化所有的推送任務。每個用戶選擇自己的隧道,為每條隧道指定推送的間隔時間。 因此同一個用戶可能有多個定時任務。 6 */ 7 public static void init() throws SchedulerException { 8 System.out.println("定時器初始化開始=============================="); 9 10 JobDataMap dataMap1 = new JobDataMap(); 11 dataMap1.put("subCode", "sdnanhuan"); 12 dataMap1.put("messageType", "all"); 13 JobKey jobKey1 = new JobKey("我的cron任務1", "我的cron任務組名1"); 14 TriggerKey triggerKey1 = new TriggerKey("我的cron觸發器名1", "我的cron觸發器組名1"); 15 16 JobKey jobKey2 = new JobKey("我的cron任務2", "我的cron任務組名1");// job的名字不能重復 17 TriggerKey triggerKey2 = new TriggerKey("我的cron觸發器名2", "我的cron觸發器組名2"); 18 19 QuartzManager.addJob(jobKey1, triggerKey1, MyQuartzJob.class, "0 0/2 * * * ?", null); 20 QuartzManager.addJob(jobKey2, triggerKey2, MyQuartzJob.class, "0 0/2 * * * ?", null); 21 22 23 } 24 }
4.最后就是在自己的業務系統里面,調用定時器工具類了。當業務提交后,如果需要創建或者修改定時器,直接在業務層調用工具類就可以了。
