既然要动态的创建任务,我们的任务信息当然要保存在某个地方了,这里我们新建一个保存任务信息对应的实体类:
/** * 计划任务信息 * * @author tq * @date 2016/5/1 */ public class ScheduleJob { /** 任务id */ private String jobId; /** 任务名称 */ private String jobName; /** 任务分组 */ private String jobGroup; /** 任务状态 0禁用 1启用 2删除*/ private String jobStatus; /** 任务运行时间表达式 */ private String cronExpression; /** 任务描述 */ private String desc; getter and setter .... }接下来我们创建测试数据,实际应用中该数据可以保存在数据库等地方,我们把任务的分组名+任务名作为任务的唯一key,和quartz中的实现方式一致:
/** 计划任务map */ private static Map<String, ScheduleJob> jobMap = new HashMap<String, ScheduleJob>(); static { for (int i = 0; i < 5; i++) { ScheduleJob job = new ScheduleJob(); job.setJobId("10001" + i); job.setJobName("data_import" + i); job.setJobGroup("dataWork"); job.setJobStatus("1"); job.setCronExpression("0/5 * * * * ?"); job.setDesc("数据导入任务"); addJob(job); } } /** * 添加任务 * @param scheduleJob */ public static void addJob(ScheduleJob scheduleJob) { jobMap.put(scheduleJob.getJobGroup() + "_" + scheduleJob.getJobName(), scheduleJob); }有了调度工厂,有了任务运行入口实现类,有了任务信息,接下来就是创建我们的定时任务了,在这里我把它设计成一个Job对应一个trigger,两者的分组及名称相同,方便管理,条理也比较清晰,在创建任务时如果不存在新建一个,如果已经存在则更新任务,主要代码如下:
//schedulerFactoryBean 由spring创建注入 Scheduler scheduler = schedulerFactoryBean.getScheduler(); //这里获取任务信息数据 List<ScheduleJob> jobList = DataWorkContext.getAllJob(); for (ScheduleJob job : jobList) { TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup()); //获取trigger,即在spring配置文件中定义的 bean id="myTrigger" CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //不存在,创建一个 if (null == trigger) { JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class) .withIdentity(job.getJobName(), job.getJobGroup()).build(); jobDetail.getJobDataMap().put("scheduleJob", job); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job .getCronExpression()); //按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build(); scheduler.scheduleJob(jobDetail, trigger); } else { // Trigger已存在,那么更新相应的定时设置 //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job .getCronExpression()); //按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey) .withSchedule(scheduleBuilder).build(); //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } }如此,可以说已经完成了我们的动态任务创建,大功告成了。有了上面的代码,添加和修改任务是不是也会了,顺道解决了?
上面我们创建的5个测试任务,都是5秒执行一次,都将调用QuartzJobFactory的execute方法,但是传入的任务信息参数不同,execute方法中的如下代码就是得到具体的任务信息,包括任务分组和任务名:
ScheduleJob scheduleJob = (ScheduleJob)context.getMergedJobDataMap().get(“scheduleJob”);
有了任务分组和任务名即确定了该任务的唯一性,接下来需要什么操作实现起来是不是就很容易了?
以后需要添加新的定时任务只需要在任务信息列表中加入记录即可,然后在execute方法中通过判断任务分组和任务名来实现你具体的操作。