JFinal Quartz 支持配置文件和持久化

    随着需求的增加,现在要定时启动一个调度和计划任务,原先写的QuartzPlugin,是持久化保存到数据库中的,从数据库中读取任务并执行。要是添加一个每天循环任务,就要在代码里写一次开始任务的代码,执行后,再注释掉,最后重启项目。否则会因为启动同name,同group的任务而报错

1org.quartz.ObjectAlreadyExistsException: Unable to store Job : 2 'group_test_1.job_test_1', because one already exists with this identification.

    原先JFinal-ext中是通过配置文件,定时循环运行的,两者结合不就是我要的吗?

思路清晰,持久化依旧,再在QuartzPlugin 中增加读取配置文件后生成调度任务,当然,这个也会保存到数据库中的,所以还要在停止的时候,终止和删除相应调度任务,否则下次启动就会报冲突了。

修改的QuartzPlugin 依旧参考了jfinal-ext,做了一些修改,原先会依赖com.google.guava:guava这个jar,因为本人有点强迫症,不喜欢jar包太多,所以能不加就不加了。

1import com.jfinal.plugin.IPlugin; 2import org.quartz.*; 3import org.quartz.impl.StdSchedulerFactory; 4import sedion.net.gppz.quartz.QuartzFactory; 5import sedion.net.gppz.utils.PropertiesUtil; 6 7import java.util.*; 8 9import static org.quartz.JobBuilder.newJob; 10import static org.quartz.TriggerBuilder.newTrigger; 11 12/** 13 * Quartz插件 14 * 15 * @author WWF 16 */ 17public class QuartzPlugin implements IPlugin { 18 19    private static final String JOB = "job"; 20 21    /** 22     * 默认配置文件 23     **/ 24    private String config = "quartz.properties"; 25    private String job_config = "jobs.properties"; 26    private Map<Job, String> jobs = new LinkedHashMap<>(); 27    private Map<String, String> jobProp; 28 29 30    public QuartzPlugin() { 31 32    } 33 34    public QuartzPlugin(String config) { 35        this.config = config; 36    } 37 38    public QuartzPlugin(String config, String job_config) { 39        this.config = config; 40        this.job_config = job_config; 41    } 42 43    @Override 44    public boolean start() { 45        try { 46            //加载配置文件 47            Properties props = PropertiesUtil.loadPropertyFile(config); 48            //实例化 49            QuartzFactory.sf = new StdSchedulerFactory(props); 50            //获取Scheduler 51            Scheduler sched = QuartzFactory.sf.getScheduler(); 52 53            //从配置文件中加载定时任务 54            loadJobsFromProperties(); 55            if (jobs.size() > 0) { 56                Set<Map.Entry<Job, String>> set = jobs.entrySet(); 57                for (Map.Entry<Job, String> entry : set) { 58                    Job job = entry.getKey(); 59                    String jobClassName = job.getClass().getName(); 60                    String jobCronExp = entry.getValue(); 61                    JobDetail jobDetail = newJob(job.getClass()) 62                            .withIdentity(jobClassName, jobClassName) 63                            .requestRecovery() 64                            .build(); 65                    CronTrigger trigger = newTrigger() 66                            .withIdentity(jobClassName, jobClassName) 67                            .withSchedule(CronScheduleBuilder.cronSchedule(jobCronExp)) 68                            .build(); 69                    sched.scheduleJob(jobDetail, trigger); 70                } 71            } 72            sched.start(); 73            return true; 74        } catch (Exception e) { 75            e.printStackTrace(); 76        } 77        return false; 78    } 79 80    @Override 81    public boolean stop() { 82        try { 83            //从配置文件中加载定时任务 84            loadJobsFromProperties(); 85            Scheduler sched = QuartzFactory.sf.getScheduler(); 86            if (jobs.size() > 0) { 87                Set<Map.Entry<Job, String>> set = jobs.entrySet(); 88                for (Map.Entry<Job, String> entry : set) { 89                    Job job = entry.getKey(); 90                    String jobClassName = job.getClass().getName(); 91                    TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobClassName); 92                    Trigger trigger = sched.getTrigger(triggerKey); 93                    if (trigger != null) { 94                        sched.pauseTrigger(triggerKey);// 停止触发器 95                        sched.unscheduleJob(triggerKey);// 移除触发器 96                        sched.deleteJob(trigger.getJobKey());// 删除任务 97                    } 98                } 99            } 100            sched.shutdown(); 101            QuartzFactory.sf = null; 102            return true; 103        } catch (Exception e) { 104            e.printStackTrace(); 105        } 106        return false; 107    } 108 109    /** 110     * 从配置文件中加载定时任务 111     */ 112    private void loadJobsFromProperties() { 113        //清空任务 114        jobs.clear(); 115        Properties properties = PropertiesUtil.loadPropertyFile(job_config); 116        jobProp = new HashMap<>((Map) properties); 117        Set<Map.Entry<String, String>> entries = jobProp.entrySet(); 118        for (Map.Entry<String, String> entry : entries) { 119            String key = entry.getKey(); 120            if (!key.endsWith(JOB) || !isEnableJob(key)) { 121                continue; 122            } 123            String jobClassName = jobProp.get(key) + ""; 124            String jobCronExp = jobProp.get(cronKey(key)) + ""; 125            try { 126                Class c = Class.forName(jobClassName); 127                jobs.put((Job) c.newInstance(), jobCronExp); 128            } catch (Exception e) { 129                e.printStackTrace(); 130            } 131        } 132    } 133 134    /** 135     * 获得cron表达式 136     * @param key 137     * @return 138     */ 139    private String cronKey(String key) { 140        return key.substring(0, key.lastIndexOf(".") + 1) + "cron"; 141    } 142 143    /** 144     * 是否开启 145     * @param key 146     * @return 147     */ 148    private boolean isEnableJob(String key) { 149        String enableKey = key.substring(0, key.indexOf(".") + 1) + "enable"; 150        Object enable = jobProp.get(enableKey); 151        if (enable != null && "true".equalsIgnoreCase((enable + "").trim())) { 152            return true; 153        } 154        return false; 155    } 156 157}

    在看jfinal-ext源码的时候,有个疑问,

    看介绍,job的配置文件是

1#JobA 2a.job=test.com.jfinal.plugin.quzrtz.JobA 3a.cron=*/5 * * * * ? 4a.enable=true

    但是在代码中,转化为map后,获取相应的key的处理是

1private String enable(String key) { 2    return key.substring(0, key.lastIndexOf(JOB)) + "enable"; 3} 4 5private String cronKey(String key) { 6    return key.substring(0, key.lastIndexOf(JOB)) + "cron"; 7}

      所以我觉得配置文件应该是

1#JobA 2a.job=test.com.jfinal.plugin.quzrtz.JobA 3a.job.cron=*/5 * * * * ? 4a.job.enable=true

或者是获得key的截取改一下

再次感谢jfinal 和jfinal-ext。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )