quartz任务调度器,有个很忧伤的限制,就是提交的任务只能指定Job class类型,具体job的实例实例化有quartz来创建,且任务每次执行都会创建一个job实例,在某些场景下,我们可能需要传递一个job实例(比如job的属性有其他方式注入),那么直接使用quartz则不太能满足,我们需要借助dataMap来传递自己的实例.例如:
CronScheduleBuilder sb = CronScheduleBuilder.cronSchedule(cronExpression); Trigger trigger = TriggerBuilder.newTrigger().withIdentity(key, GROUP).withSchedule(sb).build(); //如果任务已经在执行,则返回 if(scheduler.checkExists(trigger.getKey())){ return true; } Class<MyJob> jobClass = MyJob.class; JobDetail job = JobBuilder.newJob(jobClass).withIdentity(key, GROUP).build(); scheduler.scheduleJob(job, trigger);
其中MyJob就是我们自己的Job类,他实现了Job接口..接下来我们使用一种变通的方式来使用quartz.:
1. JobExecutor接口: 所有的可执行任务,都需要实现这个接口 .
public interface JobExecutor { public void execute(); }
2. JobProxy类:当任务调度时,充当代理层,间接的执行JobExecutor实例方法.
public class JobProxy implements Job { private static Logger log = Logger.getLogger(JobProxy.class); @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobExecutor executor = (JobExecutor)context.getJobDetail().getJobDataMap().get(Utils.WORKER_CALLER); if(executor == null){ return; } try{ executor.execute();//调用自定义的JobExecutor实例,此实例通过dataMap传递 }catch(Exception e){ e.printStackTrace(); } } }
3. JobScheduler类:任务的调度与取消
public class JobScheduler { private Scheduler scheduler; private static final String GROUP = "_default-group_"; public JobScheduler() throws Exception{ scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); } public boolean schedule(String key,String cronExpression,JobExecutor executor){ try { CronScheduleBuilder sb = CronScheduleBuilder.cronSchedule(cronExpression); Trigger trigger = TriggerBuilder.newTrigger().withIdentity(key, GROUP).withSchedule(sb).build(); //如果任务已经在执行,则返回 if(scheduler.checkExists(trigger.getKey())){ return true; } Class<JobProxy> jobClass = JobProxy.class; JobDetail job = JobBuilder.newJob(jobClass).withIdentity(key, GROUP).build(); job.getJobDataMap().put(Utils.WORKER_ID, key); //for get job.getJobDataMap().put(Utils.WORKER_CALLER, executor); //for get scheduler.scheduleJob(job, trigger); // 任务调度列表 return true; } catch (Exception e) { e.printStackTrace(); } return false; } public boolean unschedule(String key){ try { TriggerKey tk = new TriggerKey(key, GROUP); if (scheduler.checkExists(tk)) { scheduler.unscheduleJob(tk); } return true; } catch (Exception e) { e.printStackTrace(); } return false; } }
并没有特别神秘的地方,只是借助了dataMap来保存JobDeTetail的实例.