Jfinal quartz动态的增、删、暂停、恢复job

得益于quartzjfinal-ext插件可以很方便的在jfinal中配置定时任务,方法如下:

    1. 在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>
      

    1. 在jfinal中配置quartz插件:
       @Override
           public void configPlugin(Plugins me) {
               QuartzPlugin quartzPlugin = new QuartzPlugin("job.properties");
               me.add(quartzPlugin);
       }
      

      }

    2. 集成编写定时任务类:
       public class GroupVersionJo implements Job{
                   private static final Logger logger = Logger.getLogger(GroupVersionJob.class);
      
           @Override
           public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
               addVersionForAllGroup();
           }
       }
      
    3. 增加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
      
    4. 完事,:)

    但是有个缺点,就是定时任务必须事先定义好,如果我们想动态的增加,删除,暂停,恢复,暂时做不到。其实实现这些功能也很简单,改写一下QuartzPlugin插件的内容。

    QuartzPlugin这个对象中维护这一个Scheduler对象,只要能获取到这个对象,我们就能对quartz中所有的job进行修改;源插件中Scheduler对象是私有的,并且没有提供get方法,我们可以修改一下。
    1. 如下面的源码,增加了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 job
             * @param 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();
                }
                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;
            }
    
    }
    
    1. 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;
           }
       }
      
    2. 在Jfinal中注册MyQuartzPlugin对象:
       public void configPlugin(Plugins me)  {
               MyQuartzPlugin myQuartzPlugin = JobHolder.getInstance("job.properties");        
               me.add(myQuartzPlugin);  
      

      }

    3. 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 * * * ?");
      
    4. JobKey相当于任务的唯一id,Scheduler通过jobkey来管理job,JobKey对象有两个最重要的属性,namegroup,这两个属性唯一确定一个job。
       //获取scheduler中所有的jobkey
       Set<JobKey> jobKeys = myQuartzPlugin.getScheduler().getJobKeys(GroupMatcher.anyJobGroup());
      
    版权声明

    本站文章、图片、视频等(除转载外),均采用知识共享署名 4.0 国际许可协议(CC BY-NC-SA 4.0),转载请注明出处、非商业性使用、并且以相同协议共享。

    © 空空博客,本文链接:https://www.yeetrack.com/?p=1151