#Jfinal quartz動態的增、刪、暫停、恢復jobjava
得益於quartz
和jfinal-ext
插件能夠很方便的在jfinal中配置定時任務,方法以下:express
在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插件:ide
@Override public void configPlugin(Plugins me) { QuartzPlugin quartzPlugin = new QuartzPlugin("job.properties"); me.add(quartzPlugin); }
}ui
集成編寫定時任務類:this
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
配置文件:google
#天天早晨六點定時生成版本庫 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
完事,:).net
可是有個缺點,就是定時任務必須事先定義好,若是咱們想動態的增長,刪除,暫停,恢復,暫時作不到。其實實現這些功能也很簡單,改寫一下QuartzPlugin
插件的內容。插件
QuartzPlugin
這個對象中維護這一個Scheduler
對象,只要能獲取到這個對象,咱們就能對quartz中全部的job進行修改;源插件中Scheduler
對象是私有的,而且沒有提供get方法,咱們能夠修改一下。debug
以下面的源碼,增長了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());