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的实例.