ssm项目中动态Quartz定时任务的实现(定时任务存在表中,而不是在.xml中)
来源:互联网 发布:网络发展阶段 编辑:程序博客网 时间:2024/05/22 12:16
大家好,小学生又来为初级者分享一下技术了。这节我们来分享quartz动态定时任务的实现,因为楼主公司项目的需要,所以前端时间自己了解了一下动态更改的quartz定时任务功能。我刚开始也是看了需要帖子,发现大多数定时任务还是写在.xml配置里面的,这样写的最大缺点就是如果因为公司需要把定时任务执行的时间、或者是执行类更换,就需要修改.xml代码并重新提交发布版本才行。为此出了一种写到数据库里的动态定时任务技术。如下......
我在上节讲了maven创建ssm框架的多模块项目,此次也是根据上次的代码进行编写分享的,如有需要可以点击查看上篇博客 maven多模块。
1、我们需要在父项目的pom.xml文件中加入jar依赖:
<dependency><span style="white-space:pre">
<span style="white-space:pre"></span><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>1.8.6</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.2</version></dependency>
2、为了项目开发方便的需要,我们需要创建两个工具实体类:
(1)定时任务工具类QuartzManager(主要是对quartz的新增、更改、关闭等)
package com.xzhang.util;import java.util.Date;import org.quartz.CronTrigger;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.Trigger;import org.quartz.impl.StdSchedulerFactory;/** * @Title: QuartzManager.java* @Package com.xzhang.util* @Description: TODO(定时任务管理类)* @author zx * @date 2016-8-22 下午3:28:57*/ public class QuartzManager {private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory(); private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME"; private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME"; /** * @Description: 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名 * * @param jobName * 任务名 * @param cls * 任务 * @param time * 时间设置,参考quartz说明文档 * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:47:44 * @version V2.0 */ @SuppressWarnings("unchecked") public static void addJob(String jobName, Class cls, String time) { try { Scheduler sched = gSchedulerFactory.getScheduler(); JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, cls);// 任务名,任务组,任务执行类 // 触发器 CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组 trigger.setCronExpression(time);// 触发器时间设定 sched.scheduleJob(jobDetail, trigger); // 启动 if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description: 添加一个定时任务 * * @param jobName * 任务名 * @param jobGroupName * 任务组名 * @param triggerName * 触发器名 * @param triggerGroupName * 触发器组名 * @param jobClass * 任务 * @param time * 时间设置,参考quartz说明文档 * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:48:15 * @version V2.0 */ @SuppressWarnings("unchecked") public static void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String time) { try { Scheduler sched = gSchedulerFactory.getScheduler(); JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass);// 任务名,任务组,任务执行类 // 触发器 CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组 trigger.setCronExpression(time);// 触发器时间设定 sched.scheduleJob(jobDetail, trigger); // 启动 if (!sched.isShutdown()) { sched.start(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description: 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名) * * @param jobName * @param time * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:49:21 * @version V2.0 */ @SuppressWarnings("unchecked") public static void modifyJobTime(String jobName, String time) { try { Scheduler sched = gSchedulerFactory.getScheduler(); CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName,TRIGGER_GROUP_NAME); if (trigger == null) { return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(time)) { JobDetail jobDetail = sched.getJobDetail(jobName,JOB_GROUP_NAME); Class objJobClass = jobDetail.getJobClass(); removeJob(jobName); addJob(jobName, objJobClass, time); } } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description: 修改一个任务的触发时间 * * @param triggerName * @param triggerGroupName * @param time * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:49:37 * @version V2.0 */ public static void modifyJobTime(String triggerName, String triggerGroupName, String time) { try { Scheduler sched = gSchedulerFactory.getScheduler(); CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName,triggerGroupName); if (trigger == null) { return; } String oldTime = trigger.getCronExpression(); if (!oldTime.equalsIgnoreCase(time)) { CronTrigger ct = (CronTrigger) trigger; // 修改时间 ct.setCronExpression(time); // 重启触发器 sched.resumeTrigger(triggerName, triggerGroupName); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 更新任务时间:先移除、再新增 * @param triggerName * @param triggerGroupName * @param time */ public static void modifyJobTimeTrue(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String time){ //先移除 removeJob(jobName, jobGroupName, triggerName, triggerGroupName); //再新增 addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, time); } /** * @Description: 移除一个任务(使用默认的任务组名,触发器名,触发器组名) * * @param jobName * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:49:51 * @version V2.0 */ public static void removeJob(String jobName) { try { Scheduler sched = gSchedulerFactory.getScheduler(); sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器 sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器 sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务 } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description: 移除一个任务 * * @param jobName * @param jobGroupName * @param triggerName * @param triggerGroupName * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:50:01 * @version V2.0 */ public static void removeJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) { try { Scheduler sched = gSchedulerFactory.getScheduler(); sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器 sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器 sched.deleteJob(jobName, jobGroupName);// 删除任务 } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description:启动所有定时任务 * * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:50:18 * @version V2.0 */ public static void startJobs() { try { Scheduler sched = gSchedulerFactory.getScheduler(); sched.start(); } catch (Exception e) { throw new RuntimeException(e); } } /** * @Description:关闭所有定时任务 * * * @Title: QuartzManager.java * @Copyright: Copyright (c) 2014 * * @author Comsys-LZP * @date 2014-6-26 下午03:50:26 * @version V2.0 */ public static void shutdownJobs() { try { Scheduler sched = gSchedulerFactory.getScheduler(); if (!sched.isShutdown()) { sched.shutdown(); } } catch (Exception e) { throw new RuntimeException(e); } } /** * 停止一个job任务 * @param jobkey * @throws SchedulerException */ public static void pauseJob(String jobName, String groupName,String triggerName) throws SchedulerException { Scheduler sched = gSchedulerFactory.getScheduler(); //sched.pauseTrigger(triggerName, groupName); //sched.pauseJob(jobName, groupName); sched.interrupt(jobName, groupName); } /** * 恢复相关的job任务 * @param jobkey * @throws SchedulerException */ public static void resumeJob(String jobName, String groupName,String triggerName) throws SchedulerException { Scheduler sched = gSchedulerFactory.getScheduler(); //sched.resumeTrigger(triggerName, groupName); sched.resumeJob(jobName, groupName); }}(2)SpringContextUtil(spring相关的工具类,主要为了获取到项目中定义的service bean)
/** * */package com.xzhang.web;import java.util.Locale;import javax.servlet.http.HttpServletRequest;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.web.servlet.i18n.SessionLocaleResolver;/** * Spring相关工具类 * * @author Jian * @date 2012-8-15 */public class SpringContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;/** * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量. */public void setApplicationContext(ApplicationContext applicationContext) {SpringContextUtil.applicationContext = applicationContext;}/** * 取得存储在静态变量中的ApplicationContext. */public static ApplicationContext getApplicationContext() {checkApplicationContext();return applicationContext;}/** * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. */@SuppressWarnings("unchecked")public static <T> T getBean(String name) {checkApplicationContext();return (T) applicationContext.getBean(name);}/** * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. */@SuppressWarnings("unchecked")public static <T> T getBean(Class<T> clazz) {checkApplicationContext();return (T) applicationContext.getBeansOfType(clazz);}private static void checkApplicationContext() {if (applicationContext == null)throw new IllegalStateException("applicaitonContext未注入,请在spring-mvc.xml中定义SpringContextUtil");}public static String getMessage(String key, HttpServletRequest request) {return applicationContext.getMessage(key, null, getLocal(request));}public static String getMessage(String key, String[] args, HttpServletRequest request) {return applicationContext.getMessage(key, args, getLocal(request));}public static Locale getLocal(HttpServletRequest request) {Locale locale = (Locale) request.getSession().getAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME);if (locale == null) {locale = request.getLocale();}return locale;}}
-- 定时任务表CREATE TABLE t_instmt_quartz(id VARCHAR(100) PRIMARY KEY ,job_group VARCHAR(256) COMMENT '任务组',trigger_group VARCHAR(256) COMMENT '触发器组', job_name VARCHAR(128) COMMENT '任务名', trigger_name VARCHAR(128) COMMENT '触发器名', class_name VARCHAR(128) COMMENT '执行代码的类名', enable_status VARCHAR(2) DEFAULT '1' COMMENT '是否禁用:0禁用;1启用',trigger_cron VARCHAR(128) COMMENT '触发器类型(时间) */5 * * * * ?',trigger_status VARCHAR(2) COMMENT '任务状态:0关闭;1运行中;2暂停;',crate_time DATETIME COMMENT '创建时间',update_time DATETIME COMMENT '更新时间',desc_ript VARCHAR(1024) COMMENT '描述');
手动输入一条数据如下图
4、然后根据表创建实体类:QuartzManager;创建相关的dao层、service层
5、创建一个总的定时任务启动类:InstantiationTracingBeanPostProcessor,用来在spring加载完成就进行启动检索所有的定时任务并启动。
package com.xzhang.controller;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationListener;import org.springframework.context.event.ContextRefreshedEvent;import com.alibaba.fastjson.JSON;import com.xzhang.model.InstmtQuartz;import com.xzhang.service.IQuartzService;import com.xzhang.util.QuartzManager;/** * @Title: InstantiationTracingBeanPostProcessor.java* @Package com.xzhang.controller* @Description: TODO(所有定时任务的启动类:当spring启动的时候它就跟着启动)* @author zx * @date 2016-8-22 下午4:28:24*/ public class InstantiationTracingBeanPostProcessor {private IQuartzService quartzService;public IQuartzService getQuartzService() {return quartzService;}public void setQuartzService(IQuartzService quartzService) {this.quartzService = quartzService;}/* spring加载完就执行该方法:init-method="autoLoadTask" */public void autoLoadTask() {//获取到所有需要启动的quartz集合System.out.println("【系统启动】所有定时任务开启...");Map<String, Object> conditions = new HashMap<String, Object>();conditions.put("enablestatus", InstmtQuartz.ENABLE_STATUS_YES);conditions.put("triggerstatus", "");List<InstmtQuartz> quartzList = quartzService.getInstmtQuartzList(conditions);if(null == quartzList)return;for(int i=0;i<quartzList.size();i++){System.out.println("定时任务个数:"+quartzList.size());try {QuartzManager.addJob(quartzList.get(i).getJobname(), quartzList.get(i).getJobgroup(), quartzList.get(i).getTriggername(), quartzList.get(i).getTriggergroup(), Class.forName(quartzList.get(i).getClassname()), quartzList.get(i).getTriggercron());} catch (ClassNotFoundException e) {e.printStackTrace();}}}}
<!-- 定义SpringContextUtil工具类 --><bean id="springContextUtil" class="com.xzhang.web.SpringContextUtil" />
<!-- 定时任务:要求所有的定时任务在spring启动之后跟着启动 --><bean id="instantiationTracingBeanPostProcessor" init-method="autoLoadTask" class="com.xzhang.controller.InstantiationTracingBeanPostProcessor" ><property name="quartzService" ref="quartzService" /></bean>
如上代码所示:(1)第一个配置是为了定义声明SpringContextUtil,因为利用了这个工具类去获取了项目中注解的service;
(2)第二个配置是为了在spring启动完成后就执行InstantiationTracingBeanPostProcessor类中的方法autoLoadTask,并注入了quartzService
7、编写一个测试的定时任务执行类,如下:
package com.xzhang.controller;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;import org.apache.log4j.Logger;import org.quartz.InterruptableJob;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.UnableToInterruptJobException;import com.xzhang.model.User;import com.xzhang.service.IUserService;import com.xzhang.web.SpringContextUtil;/** * 定时任务--打印测试定时任务是否成功 * @author zx * */public class TestQuartzTask implements InterruptableJob {protected Logger log = Logger.getLogger(this.getClass());private boolean _interrupted = false;/*此处引入相关的service*/private IUserService userService = SpringContextUtil.getBean("userService");@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {if(null == userService){System.out.println("userService为null");}SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sf.format(new Date())+"定时任务TestQuartzTask.class启动!!!");/* * 获取所有的用户列表,并循环打印 * */List<User> users = userService.getAll();if(null != users && users.size()>0){for(User u : users){//判断是否点击了‘立刻停止’if(_interrupted) { System.out.println("定时任务ExpectedBillSmsTask.class立刻停止!!!"); return; }System.out.println(sf.format(new Date())+":"+u.getName());}}}@Overridepublic void interrupt() throws UnableToInterruptJobException {System.out.println("【关闭】interrupt执行立刻停止:test定时发送...");log.info("【关闭】interrupt执行立刻停止:test定时发送...");_interrupted = true;}}注:这个执行类实现了InterruptableJob类,之所以实现这个类主要是想利用InterruptableJob类中private boolean _interrupted = false;这个作用是当在定时任务管理界面点击【立即停止】时,会让_interrupted =true,会中止for循环,也就停止了定时任务的执行了。
好了,就到这里吧,如果大家有疑问可以随时联系楼主这个小学生,楼主的代码里也许会有不合理的地方,欢迎大家指出、相互交流。
楼主QQ:752058871
- ssm项目中动态Quartz定时任务的实现(定时任务存在表中,而不是在.xml中)
- 在项目中集成定时任务--->Quartz
- QuartZ--Spring中定时任务的实现
- Quartz(一)在Spring中设置动态定时任务
- Spring+Quartz 从数据库中获取定时任务和定时时间,动态实现对定时任务的增删改查
- Quartz在Spring中动态设置cronExpression (spring设置动态定时任务)(转的)
- 用关Quartz在Spring中设置动态定时任务
- Quartz在Spring中设置动态定时任务
- Quartz在Spring中设置动态定时任务
- Quartz在Spring中设置动态定时任务 .
- Quartz在Spring中设置动态定时任务
- 在SSM框架中配置定时任务
- 在SSM框架中配置定时任务
- Spring Boot中实现Quartz动态定时任务
- 定时任务-在spring中配置quartz
- 定时任务-在spring中配置quartz
- 定时任务--在Spring 中配置Quartz
- 定时任务-在spring中配置quartz
- centos tomcat 搭建https 服务器
- 使用Python
- UITextField 密码明文及密文切换问题
- Layout组件综合训练
- swift调用OC代码和第三方库
- ssm项目中动态Quartz定时任务的实现(定时任务存在表中,而不是在.xml中)
- 动态规划-最优解
- 弧线运动
- 重拾C语言之指针篇(三)
- Android笔记:ToolBar和SearchView使用
- 村花的swift学习笔记2
- 对WM_NCHITTEST消息的了解+代码实例进行演示
- Java虚拟机参数 -XX等相关参数应用
- Spring AOP 不同配置方式产生的冲突问题