发布时间:2018-05-06作者:laosun阅读(89727)
Cron4j 动态读取任务 cron 表达式指令(数据库读取),(可手动开始、修改表达式指令后立即生效,可手动及时停止等操作),本测试实在 Jfinal 框架下测试可能会有部分 Jfinal 的代码
以下代码测试实在 Jfinal 框架上进行测试的,有部分类是Jfinal作者封装的, 但是原理都差不多。主要设计就在 cron4jMap这块,只需要把定时调度类放进去,那么修改这个map中的这个类,就可以实现手动开始、停止等操作了。 当然这个cron4jMap 也可以放到redis中。
首先我们创建一个表,来存储cron4j的详细信息
CREATE TABLE `t_cron4j` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '唯一标识', `name` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '定时名称', `package_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '执行类', `cron` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '表达式', `daemon` int(1) NOT NULL DEFAULT 1 COMMENT '表示调试线程是否设置为守护线程,默认值为 true,守护线程会在 tomcat 关闭时自动关闭', `enable` int(1) NOT NULL DEFAULT 1 COMMENT '表示该任务是否有效,默认值为 true,为 false 时该任务无效,不会被调用', `stu` int(1) NULL DEFAULT 1 COMMENT '状态1:正常 0:停止禁用 -1:删除', `start_execute` int(1) NULL DEFAULT 0 COMMENT '启动后是否立即执行一次(包括添加、修改后立即执行一次)', `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '简介说明描述', `last_execute_time` timestamp(0) NULL DEFAULT NULL COMMENT '最后一次执行时间', `add_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间', `update_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后一次更新时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'cron4j轮询定时管理' ROW_FORMAT = Dynamic;
首先创建封装类,专门执行cron4j的开始、停止和更新操作
/** java cron4j 定时调度 **/ public static final Map<String, Cron4jPlugin> cron4jMap = new HashMap<String, Cron4jPlugin>(); /** * 添加cron4j调度 * @author sun * @param cron4j */ public static void addCron4j(TCron4j cron4j){ try { /** 这块容易报错 **/ Object taskObj = classNewInstance(cron4j.getStr("package_class")); /** 只接受Runnable的定时器 **/ if (taskObj instanceof Runnable) { Cron4jPlugin cp = new Cron4jPlugin(); Runnable task = (Runnable)taskObj; if(cron4j.getInt("start_execute")==1){//启动立即执行一次 Thread t1 = new Thread(new Runnable() { public void run() { task.run(); } }); t1.start(); } cp.addTask(cron4j.getStr("cron"), task, cron4j.getInt("daemon")==1?true:false, cron4j.getInt("enable")==1?true:false); cp.start(); /** 放入map中 **/ CommonUtils.cron4jMap.put(cron4j.getStr("uuid"), cp); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 更新cron4j任务调度(先删除、后添加的操作原理) * @author sun * @param cron4j */ public static void updateCron4j(TCron4j cron4j){ deleteCron4j(cron4j); addCron4j(cron4j); } /** * 删除停止cron4j任务调度 * @author sun * @param cron4j */ public static void deleteCron4j(TCron4j cron4j){ String uuid = cron4j.getStr("uuid"); if(CommonUtils.cron4jMap.get(uuid)!=null){ Cron4jPlugin cp = CommonUtils.cron4jMap.get(uuid); if(cp!=null){ cp.stop(); } CommonUtils.cron4jMap.remove(uuid); } } /** * Java 反射 * @author sun * @param taskClass * @return * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public static Object classNewInstance(String taskClass) throws InstantiationException, IllegalAccessException, ClassNotFoundException { if (StrKit.isBlank(taskClass)) { throw new IllegalArgumentException(".class" + " not found."); } taskClass = taskClass.trim(); Object taskObj = Class.forName(taskClass).newInstance(); return taskObj; }
以上代码为初始测试代码,实际使用请记得对异常控制一下。
插入一条数据
INSERT INTO `t_cron4j`(`id`, `uuid`, `name`, `package_class`, `cron`, `daemon`, `enable`, `stu`, `type`, `start_execute`, `description`, `last_execute_time`, `add_time`, `update_time`) VALUES (1, '1f33830233fc4d00aa6cc5e2d2569555', '测试', 'com.sunjs.job.TestJob', '* * * * *', 1, 1, -1, 2, 1, '测试小李子', '2018-05-04 09:58:12', '2018-05-04 09:58:12', '2018-05-04 16:15:17');
这条数据的意思就是:每分钟执行一次。
执行类:com.sunjs.job.TestJob
package com.sunjs.job; public class TestJob implements Runnable { public void run() { System.out.println("Hello World!"); } }
动态修改cron4j到此就完成了,可以从后台开发出对 t_cron4j 表的增删改查,新增的时候调用增加方法,删除调用删除方法,修改调用修改方法。真正的做到后台动态控制,而不必每次需要修改properties文件,还得重启,挺麻烦的。
这种做法呢,也需要在系统启动的时候调用一次这个 t_cron4j 表,将所有的生效的数据全部获取出来进行加载。
版权属于: 技术客
原文地址: https://www.sunjs.com/article/detail/fa02f4b3ee20475488f393472bf0ecfa.html
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。