文档章节

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

超级大富
 超级大富
发布于 2015/05/27 21:07
字数 790
阅读 619
收藏 4

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

org.quartz.ObjectAlreadyExistsException: Unable to store Job :
 '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包太多,所以能不加就不加了。

import com.jfinal.plugin.IPlugin;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import sedion.net.gppz.quartz.QuartzFactory;
import sedion.net.gppz.utils.PropertiesUtil;

import java.util.*;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

/**
 * Quartz插件
 *
 * @author WWF
 */
public class QuartzPlugin implements IPlugin {

    private static final String JOB = "job";

    /**
     * 默认配置文件
     **/
    private String config = "quartz.properties";
    private String job_config = "jobs.properties";
    private Map<Job, String> jobs = new LinkedHashMap<>();
    private Map<String, String> jobProp;


    public QuartzPlugin() {

    }

    public QuartzPlugin(String config) {
        this.config = config;
    }

    public QuartzPlugin(String config, String job_config) {
        this.config = config;
        this.job_config = job_config;
    }

    @Override
    public boolean start() {
        try {
            //加载配置文件
            Properties props = PropertiesUtil.loadPropertyFile(config);
            //实例化
            QuartzFactory.sf = new StdSchedulerFactory(props);
            //获取Scheduler
            Scheduler sched = QuartzFactory.sf.getScheduler();

            //从配置文件中加载定时任务
            loadJobsFromProperties();
            if (jobs.size() > 0) {
                Set<Map.Entry<Job, String>> set = jobs.entrySet();
                for (Map.Entry<Job, String> entry : set) {
                    Job job = entry.getKey();
                    String jobClassName = job.getClass().getName();
                    String jobCronExp = entry.getValue();
                    JobDetail jobDetail = newJob(job.getClass())
                            .withIdentity(jobClassName, jobClassName)
                            .requestRecovery()
                            .build();
                    CronTrigger trigger = newTrigger()
                            .withIdentity(jobClassName, jobClassName)
                            .withSchedule(CronScheduleBuilder.cronSchedule(jobCronExp))
                            .build();
                    sched.scheduleJob(jobDetail, trigger);
                }
            }
            sched.start();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean stop() {
        try {
            //从配置文件中加载定时任务
            loadJobsFromProperties();
            Scheduler sched = QuartzFactory.sf.getScheduler();
            if (jobs.size() > 0) {
                Set<Map.Entry<Job, String>> set = jobs.entrySet();
                for (Map.Entry<Job, String> entry : set) {
                    Job job = entry.getKey();
                    String jobClassName = job.getClass().getName();
                    TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobClassName);
                    Trigger trigger = sched.getTrigger(triggerKey);
                    if (trigger != null) {
                        sched.pauseTrigger(triggerKey);// 停止触发器
                        sched.unscheduleJob(triggerKey);// 移除触发器
                        sched.deleteJob(trigger.getJobKey());// 删除任务
                    }
                }
            }
            sched.shutdown();
            QuartzFactory.sf = null;
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 从配置文件中加载定时任务
     */
    private void loadJobsFromProperties() {
        //清空任务
        jobs.clear();
        Properties properties = PropertiesUtil.loadPropertyFile(job_config);
        jobProp = new HashMap<>((Map) properties);
        Set<Map.Entry<String, String>> entries = jobProp.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            if (!key.endsWith(JOB) || !isEnableJob(key)) {
                continue;
            }
            String jobClassName = jobProp.get(key) + "";
            String jobCronExp = jobProp.get(cronKey(key)) + "";
            try {
                Class c = Class.forName(jobClassName);
                jobs.put((Job) c.newInstance(), jobCronExp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获得cron表达式
     * @param key
     * @return
     */
    private String cronKey(String key) {
        return key.substring(0, key.lastIndexOf(".") + 1) + "cron";
    }

    /**
     * 是否开启
     * @param key
     * @return
     */
    private boolean isEnableJob(String key) {
        String enableKey = key.substring(0, key.indexOf(".") + 1) + "enable";
        Object enable = jobProp.get(enableKey);
        if (enable != null && "true".equalsIgnoreCase((enable + "").trim())) {
            return true;
        }
        return false;
    }

}

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

    看介绍,job的配置文件是

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

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

private String enable(String key) {
    return key.substring(0, key.lastIndexOf(JOB)) + "enable";
}

private String cronKey(String key) {
    return key.substring(0, key.lastIndexOf(JOB)) + "cron";
}

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

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

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

再次感谢jfinal 和jfinal-ext。


© 著作权归作者所有

下一篇: JFinal 整合Quartz
超级大富

超级大富

粉丝 49
博文 20
码字总数 26710
作品 1
温州
技术主管
私信 提问
jfinal中对分布式事务的支持

@JFinal 你好,想跟你请教个问题:在实际项目过程中,用到了quartz组件。为了保证quartz组件中任务额事务与service层事务在同一事务控制中,使用配置文件将quartz组件的事务控制交由应用服务...

qiran
2015/06/24
1K
1
JFinal 整合Quartz

项目中要加入调度和计划任务等功能,所以选择Quartz调度插件,原先都是在S2SH上整合的。现在项目用JFinal框架,不得不说JFinal框架的定制性真好,可以自己根据项目要求进行修改,并且很节省时...

超级大富
2014/03/09
2.5K
20
JFinal Extensions 3.1.3 发布,JFinal 扩展

JFinal Extensions 3.1.3 发布,这次是一个小版本更新,主要是功能的小改进和bug修复。 Quartzplugin 兼容quartz 1.X 和 2.X 两大版本 Quartzplugin 支持原生quartz.properties配置文件 PoiR...

绝望的八皮
2015/02/03
6.3K
32
JFinal Extensions 1.1 发布,JFinal 扩展

Jfinal-ext是对java极速web框架 jfinal 的一个扩充,主要利用jfinal的plugin机制集成各种第三方框架,像spring一样,简化开发者的学习应用成本,使用时请将jfinal.jar先引入工程。 changelo...

绝望的八皮
2012/10/26
702
12
JFinal 1.2 发布,JAVA极速WEB+ORM框架

转间眼JFinal开源已经十个月了,在过去的一年里JFinal经历了12次版本更新,在保持了微内核架构的同时持续完善功能、提升开发体验。不知道大家是否正在使用JFinal做项目,是否体验到了极速开发...

JFinal
2013/01/28
5K
73

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
13
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部