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.最后就是在自己的业务系统里面,调用定时器工具类了。当业务提交后,如果需要创建或者修改定时器,直接在业务层调用工具类就可以了。