#Jfinal quartz动态的增、删、暂停、恢复job
得益于quartz
和jfinal-ext
插件可以很方便的在jfinal中配置定时任务,方法如下:
-
在pom.xml中增加依赖:
<dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-ext</artifactId> <version>3.1.4</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.2</version> </dependency>
-
在jfinal中配置quartz插件:
@Override public void configPlugin(Plugins me) { QuartzPlugin quartzPlugin = new QuartzPlugin("job.properties"); me.add(quartzPlugin); }
}
-
集成编写定时任务类:
public class GroupVersionJo implements Job{ private static final Logger logger = Logger.getLogger(GroupVersionJob.class); @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { addVersionForAllGroup(); } }
-
增加
job.properties
配置文件:#每天早晨六点定时生成版本库 a.job=com.meilishuo.autotest.agile.quartz.GroupVersionJob a.cron=0 0 6 * * ? a.enable=true #提测单的获取,每分钟一次 b.job=com.meilishuo.autotest.agile.quartz.ProductCardJob b.cron=0 */1 * * * ? b.enable=true
-
完事,:)
但是有个缺点,就是定时任务必须事先定义好,如果我们想动态的增加,删除,暂停,恢复,暂时做不到。其实实现这些功能也很简单,改写一下QuartzPlugin
插件的内容。
QuartzPlugin
这个对象中维护这一个Scheduler
对象,只要能获取到这个对象,我们就能对quartz中所有的job进行修改;源插件中Scheduler
对象是私有的,并且没有提供get方法,我们可以修改一下。
-
如下面的源码,增加了get、set方法,增加了一个
addJobWhenRun
方法:package com.meilishuo.autotest.agile.quartz; import com.google.common.base.Throwables; import com.google.common.collect.Maps; import com.jfinal.ext.kit.Reflect; import com.jfinal.ext.kit.ResourceKit; import com.jfinal.kit.StrKit; import com.jfinal.log.Logger; import com.jfinal.plugin.IPlugin; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.util.Date; import java.util.Map; import java.util.Set; /** * Created by Xuemeng Wang on 16-4-20. */ public class MyQuartzPlugin implements IPlugin { public static final String VERSION_1 = "1"; private static final String JOB = "job"; private final Logger logger = Logger.getLogger(getClass()); private Map<Job, String> jobs = Maps.newLinkedHashMap(); private String version; private SchedulerFactory sf; private Scheduler scheduler; private String jobConfig; private String confConfig; private Map<String, String> jobProp; public MyQuartzPlugin(String jobConfig, String confConfig) { this.jobConfig = jobConfig; this.confConfig = confConfig; } public MyQuartzPlugin(String jobConfig) { this.jobConfig = jobConfig; } public MyQuartzPlugin() { } public MyQuartzPlugin add(String jobCronExp, Job job) { jobs.put(job, jobCronExp); return this; } @Override public boolean start() { loadJobsFromProperties(); startJobs(); return true; } private void startJobs() { //没有修改,请去阅读源码 } public void loadJobsFromProperties() { //没有修改,请去阅读源码 } /** * added by xuemeng wang,动态的增加一个job,这部分代码就是上面startJobs大部分的代码 * [@param](https://my.oschina.net/u/2303379) job * [@param](https://my.oschina.net/u/2303379) cronExp */ public void addJobWhenRun(Job job, String cronExp) { String jobClassName = job.getClass().getName(); String jobCronExp = cronExp; JobDetail jobDetail; CronTrigger trigger; //JobDetail and CornTrigger are classes in 1.x version,but are interfaces in 2.X version. if (VERSION_1.equals(version)) { jobDetail = Reflect.on("org.quartz.JobDetail").create(jobClassName, jobClassName, job.getClass()).get(); trigger = Reflect.on("org.quartz.CronTrigger").create(jobClassName, jobClassName, jobCronExp).get(); } else { jobDetail = Reflect.on("org.quartz.JobBuilder").call("newJob", job.getClass()).call("withIdentity", jobClassName, jobClassName) .call("build").get(); //Object temp = Reflect.on("org.quartz.TriggerBuilder").call("newTrigger").get(); //temp = Reflect.on(temp).call("withIdentity", jobClassName, jobClassName).get(); //temp = Reflect.on(temp).call("withSchedule", //Reflect.on("org.quartz.CronScheduleBuilder").call("cronSchedule", jobCronExp).get()) //.get(); //trigger = Reflect.on(temp).call("build").get(); //不使用反射,解决在jdk1.8中启动失败的问题 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger(); triggerBuilder.withIdentity(jobClassName, jobClassName); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobCronExp); triggerBuilder.withSchedule(cronScheduleBuilder); trigger = (CronTrigger)triggerBuilder.build(); } logger.info("jobkey ---> " + jobDetail.getKey()); //这里获取的jobkey很重要,后续删除、暂停、恢复都需要这个jobkey,可以将jobkey维护到db中,方便集中管理。 Date ft = Reflect.on(scheduler).call("scheduleJob", jobDetail, trigger).get(); logger.debug(Reflect.on(jobDetail).call("getKey") + " has been scheduled to run at: " + ft + " " + "and repeat based on expression: " + Reflect.on(trigger).call("getCronExpression")); } public MyQuartzPlugin version(String version) { this.version = version; return this; } public MyQuartzPlugin confConfig(String confConfig) { this.confConfig = confConfig; return this; } public MyQuartzPlugin jobConfig(String jobConfig) { this.jobConfig = jobConfig; return this; } //为Scheduler对象增加一个get方法,让其在外部可以访问 public Scheduler getScheduler() { return scheduler; }
}
-
jfinal在configPlugin方法中,会new一个QuartzPlugin对象,注册到jfinal中。但是我没有找到从Jfinal框架再获取QuartzPlugin对象的方法,因此,我把MyQuartzPlugin对象设置成全局变量,用单例模式保证其只有一个实例。
/** * Created by Xuemeng Wang on 16-4-20. */ public class JobHolder { private static MyQuartzPlugin myQuartzPlugin; private JobHolder() {} public static MyQuartzPlugin getInstance(String configFileName) { if(null == myQuartzPlugin) { myQuartzPlugin = new MyQuartzPlugin(configFileName); } return myQuartzPlugin; } }
-
在Jfinal中注册MyQuartzPlugin对象:
public void configPlugin(Plugins me) { MyQuartzPlugin myQuartzPlugin = JobHolder.getInstance("job.properties"); me.add(myQuartzPlugin);
}
-
jfinal启动后,会把配置文件中的定时任务跑起来,增加、删除、暂停、恢复的方法如下:
MyQuartzPlugin myQuartzPlugin = JobHolder.getInstance(("job.properties")); //暂停job myQuartzPlugin.getScheduler().pauseJob(new JobKey("com.meilishuo.autotest.agile.quartz.UserSyncJob", "com.meilishuo.autotest.agile.quartz.UserSyncJob")); //恢复job myQuartzPlugin.getScheduler().resumeJob(new JobKey("com.meilishuo.autotest.agile.quartz.UserSyncJob", "com.meilishuo.autotest.agile.quartz.UserSyncJob")); //删除job result = myQuartzPlugin.getScheduler().deleteJob(new JobKey("com.meilishuo.autotest.agile.quartz.UserSyncJob", "com.meilishuo.autotest.agile.quartz.UserSyncJob")); //增加job MyQuartzPlugin myQuartzPlugin = JobHolder.getInstance("job.properties"); Job job = new UserSyncJob(); myQuartzPlugin.addJobWhenRun(job, "0 */1 * * * ?");
-
JobKey相当于任务的唯一id,
Scheduler
通过jobkey来管理job,JobKey
对象有两个最重要的属性,name
和group
,这两个属性唯一确定一个job。//获取scheduler中所有的jobkey Set<JobKey> jobKeys = myQuartzPlugin.getScheduler().getJobKeys(GroupMatcher.anyJobGroup());
我的博客: http://www.yeetrack.com/?p=1151