quartz的使用比较普遍,动态修改修改也比较成型,这里只列举自己在项目中已比较简单的方式来实现的quartz的动态修改。
首先把所有quartz任务定义放入放入数据库中,对应java自定义实体如下
public class SchedulerJob { public static final int STATUS_USED = 1; //可用状态 /** 任务id spring的bean名称*/ private String jobId; /** 任务名称 */ private String jobName; /** 任务状态 0停用 1启用 */ private Integer jobStatus; /** 任务运行时间表达式 */ private String cronExpression;
对应定义任务运行的接口定义
/** * * @ClassName: SchedulerJobBean * @Description: 定时任务Bean的顶级接口 * @Create In 2014年9月23日 By lee */ public interface SchedulerJobBean { /** * 定时任务执行业务逻辑方法体 * @Methods Name execute * @Create In 2014年9月23日 By lee * @param context */ public void execute(JobExecutionContext context); }
SchedulerJob中的jobId即是SchedulerJobBean实现的spring bean id,因此所有定时任务需实现SchedulerJobBean接口。
然后自定义一个quartz运行工厂类,来执行定时任务实现
/** * 单机任务执行工厂 * @ClassName: SingleQuartzJobFactory * @Description: TODO * @Create In 2015年1月14日 By lee */ @DisallowConcurrentExecution public class SingleQuartzJobFactory implements Job { private static final Logger log = LoggerFactory.getLogger(SingleQuartzJobFactory.class); public void execute(JobExecutionContext context) throws JobExecutionException { SchedulerJob scheduleJob = (SchedulerJob)context.getMergedJobDataMap().get("scheduleJob"); try{ SchedulerJobBean jobBean = (SchedulerJobBean) ContextHolder.getBean(scheduleJob.getJobId()); jobBean.execute(context); } catch (Exception ex){ log.error("====================Scheduler-error-begin===================="); log.error(ex.toString()); StackTraceElement[] element = ex.getStackTrace(); for(int i=0;i<element.length;i++){ log.error("位置:"+element[i]); } log.error("====================Scheduler-error-end===================="); } } }
最后需要一个加载器来实现加载功能,这里我封装了一个manager来处理。由于为集群情况考虑,先封装了一个基类管理器(其中关于集群部分下篇介绍)
/** * quartz任务管理器基类 * @ClassName: AbstractQuartzManager * @Description: TODO * @Create In 2015年1月14日 By lee */ public abstract class AbstractQuartzManager { private static final Logger log = LoggerFactory.getLogger(AbstractQuartzManager.class); private static String schedulerState = ""; //定任务状态(single单机状态、cluster集群状态、null未启动状态) public static final String STATE_SINGLE = "single"; //单机状态 public static final String STATE_CLUSTER = "cluster"; //集群状态 public static final String STATE_NULL = "null"; //未启动状态 /** * 更新定时任务 * @Methods Name update * @Create In 2014年9月23日 By lee * @param job * @throws SchedulerException */ public static void update(SchedulerJob oldJob, SchedulerJob newJob) throws SchedulerException{ if(oldJob==null){ if(SchedulerJob.STATUS_USED==newJob.getJobStatus()){ create(newJob); } }else{ SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); //获取触发器标识 TriggerKey triggerKey = TriggerKey.triggerKey(oldJob.getJobId(), SchedulerJob.JOB_GOURP); //获取触发器trigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); if(null!=trigger){//如果已存在任务 delete(oldJob); } if(SchedulerJob.STATUS_USED==newJob.getJobStatus()){ create(newJob); } } } public static void update(SchedulerJob job) throws SchedulerException{ if(job!=null){ SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); //获取触发器标识 TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobId(), SchedulerJob.JOB_GOURP); //获取触发器trigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); if(null!=trigger){//如果已存在任务 delete(job); } if(SchedulerJob.STATUS_USED==job.getJobStatus()){ create(job); } } } /** * 新建任务 * @Methods Name create * @Create In 2014年9月23日 By lee * @param scheduleJob * @throws SchedulerException */ public static void create(SchedulerJob scheduleJob) throws SchedulerException { SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); //创建任务 JobDetail jobDetail = null; if(AbstractQuartzManager.getState().equalsIgnoreCase(AbstractQuartzManager.STATE_SINGLE)){ jobDetail = JobBuilder.newJob(SingleQuartzJobFactory.class) .withIdentity(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP) .build(); }else if(AbstractQuartzManager.getState().equalsIgnoreCase(AbstractQuartzManager.STATE_CLUSTER)){ jobDetail = JobBuilder.newJob(ClusterQuartzJobFactory.class) .withIdentity(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP) .build(); }else{ return; } jobDetail.getJobDataMap().put("scheduleJob", scheduleJob); //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob .getCronExpression()); //按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP) .withSchedule(scheduleBuilder) .build(); scheduler.scheduleJob(jobDetail, trigger); log.debug("=====定时任务["+scheduleJob.getJobId()+"/"+scheduleJob.getJobName()+"]载入成功====="); } /** * 修改 * @Methods Name modify * @Create In 2014年9月23日 By lee * @param scheduleJob * @throws SchedulerException */ public static void modify(SchedulerJob scheduleJob) throws SchedulerException { SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP); //获取触发器trigger CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // Trigger已存在,那么更新相应的定时设置 //表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob .getCronExpression()); //按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder() .withIdentity(triggerKey) .withSchedule(scheduleBuilder) .build(); //按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); log.debug("=====定时任务["+scheduleJob.getJobId()+"/"+scheduleJob.getJobName()+"]更新成功====="); } /** * 暂停任务 * @Methods Name pause * @Create In 2014年9月23日 By lee * @param scheduleJob * @throws SchedulerException */ public static void pause(SchedulerJob scheduleJob) throws SchedulerException { SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP); scheduler.pauseJob(jobKey); log.debug("=====定时任务["+scheduleJob.getJobId()+"/"+scheduleJob.getJobName()+"]暂停成功====="); } /** * 恢复任务 * @Methods Name resume * @Create In 2014年9月23日 By lee * @param scheduleJob * @throws SchedulerException */ public static void resume(SchedulerJob scheduleJob) throws SchedulerException { SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP); scheduler.resumeJob(jobKey); log.debug("=====定时任务["+scheduleJob.getJobId()+"/"+scheduleJob.getJobName()+"]恢复成功====="); } /** * 删除任务 * @Methods Name delete * @Create In 2014年9月23日 By lee * @param scheduleJob * @throws SchedulerException */ public static void delete(SchedulerJob scheduleJob) throws SchedulerException { SchedulerFactoryBean schedulerFactoryBean = ContextHolder.getBean(SchedulerFactoryBean.class); Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getJobId(), SchedulerJob.JOB_GOURP); scheduler.deleteJob(jobKey); log.debug("=====定时任务["+scheduleJob.getJobId()+"/"+scheduleJob.getJobName()+"]注销成功====="); } /** * 获取定时任务状态配置(single表示单机版,cluster表示集群版) * @Methods Name getState * @Create In 2015年1月14日 By lee * @return */ public static String getState(){ if(StringUtils.isEmpty(schedulerState)){ schedulerState = PropertiesUtils.getProperty("app.scheduler.state"); } return schedulerState; } }针对单机增加一个SingleQuartzManager实现如下
/** * Quartz单机管理器 * @ClassName: SingleQuartzManager * @Create In 2014年12月31日 By lee */ public class SingleQuartzManager extends AbstractQuartzManager{ private static final Logger log = LoggerFactory.getLogger(SingleQuartzManager.class); public static final int STATE_RUN = 1; //运行状态 public static final int STATE_WAIT = 0; //等待状态 /** * 启动所有定时任务 * @throws SchedulerException * @Methods Name startAll * @Create In 2014年9月23日 By lee */ public static void startAll() throws SchedulerException{ if(AbstractQuartzManager.getState().equalsIgnoreCase(AbstractQuartzManager.STATE_SINGLE)){ SchedulerJobService schedulerJobService = ContextHolder.getBean(SchedulerJobService.class); List<SchedulerJob> jobs = schedulerJobService.findAll(); for(SchedulerJob job : jobs){ if(SchedulerJob.STATUS_USED==job.getJobStatus()){ create(job); } } log.debug("=====定时任务启动完成====="); } } }
最最后补上配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> </bean> </beans>
这个实现只需要在spring中声明一下schedulerFactory,其他全部交给代码来完成。主要完成以下几个功能:
- 减少quartz配置;
- 通过配置文件动态修改quartz是否运行(我的配置文件也是动态的);
- 动态修改定时任务的状态预计运行规则。
PS:
- 代码中ContextHolder.getBean及获取spring bean实例方法类。
- SingleQuartzManager.startAll()项目启动的时候调一下就不提供代码了
相关推荐
Spring 3.0 和 Quartz 1.6.0 结合使用是企业级应用中常见的定时任务解决方案。Spring 是一个强大的Java应用程序框架,提供了依赖注入、AOP(面向切面编程)以及众多其他功能,而Quartz则是一个开源的作业调度框架,...
在这个“quartz_springbatch_dynamic”项目中,我们将看到如何将这两个强大的工具结合起来,以实现动态集群环境中的定时任务执行,并使用MySQL作为数据存储。 Quartz是一个开源的作业调度框架,允许开发者创建、...
Quartz和Spring-Quartz是两个在Java世界中广泛使用的定时任务管理框架。Quartz是一个开源的作业调度框架,允许应用程序定义和调度任务在特定时间执行。而Spring-Quartz则是Spring框架对Quartz的集成,它使得在Spring...
实现异步处理,定时任务,整合Quartz Job以及Spring Task 邮件管理功能, 整合spring-boot-starter-mail发送邮件等, 数据源:druid 用户管理,菜单管理,角色管理,代码生成 运行环境 jdk8+oracle+redis+...
本人搭的项目,可以正常运行。用于自己存留备份,若有人需要也可下载。 项目用到的技术点: ...quartz持久化到Oracle数据库+ log4j+ Excel处理(只有工具代码,使用代码没放)+ spring-test(测试例子)+ bootstrap
Quartz和Spring结合使用可以构建强大的定时任务管理系统。Quartz是一个开源的作业调度框架,它允许应用程序定义和调度任务在特定时间执行。而Spring框架则提供了丰富的依赖注入和管理功能,使得集成Quartz变得更加...
"quartz2.2.1 API"可能是指Quartz Scheduler的API文档,这是一个开源的作业调度框架,可与Spring集成,用于在应用中安排任务执行。虽然它与主题中的XSD文件不直接相关,但当涉及到复杂的缓存策略时,可能需要结合...
在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"spring+springMVC+mybatis+quartz动态定时任务创建"就是一个常见的技术栈,用于实现这样的目标。这个组合充分利用了各组件的优势,提供了强大的后端服务支持...
存储过程等),用Redis做中间缓存,缓存数据 实现异步处理,定时任务,整合Quartz Job以及Spring Task 邮件管理功能, 整合spring-boot-starter-mail发送邮件等, 数据源:druid 用户管理,菜单管理,角色管理,代码...
确保包含 `quartz.jar`、`spring-context.jar` 及其他相关的 Spring 库。 2. **配置 Quartz**:创建 `quartz.properties` 文件来配置 Quartz 的基本属性,如线程池大小、作业存储方式等。还可以在配置文件中指定 ...
Quartz + spring简单配置多个任务调度 spring配置文件 简单配置
通过 "quartz-spring-demo",开发者可以快速理解如何在 Spring 应用程序中集成和使用 Quartz,从而实现灵活的定时任务调度。这个简单的演示项目是一个学习和实践 Quartz 和 Spring 整合的好起点。
而当我们提到`spring-context-support.jar`和`quartz-all-1.6.0.jar`时,我们是在讨论Spring框架中的任务调度功能,特别是与Quartz库的集成。 `spring-context`是Spring框架的核心模块之一,它提供了上下文...
包含翻译后的API文档:spring-context-support-5.3.15-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.springframework:spring-context-support:5.3.15; 标签:spring、context、springframework、...
标题中的"spring-context-support-4.2.2和quartz-2.2.3所需Jar包"涉及到两个关键的Java库:Spring Context Support 4.2.2版本和Quartz Scheduler 2.2.3版本。这两个库在企业级Java应用开发中扮演着重要角色,特别是...
基于spring-boot+quartz的CRUD任务管理系统源码+项目说明.zip基于spring-boot+quartz的CRUD任务管理系统源码+项目说明.zip基于spring-boot+quartz的CRUD任务管理系统源码+项目说明.zip基于spring-boot+quartz的CRUD...
将 Quartz 整合到 Spring 中,可以方便地管理和控制定时任务,使得应用更具灵活性。 **1. 添加依赖** 首先,我们需要在项目中引入 Quartz 和 Spring 的相关依赖。如果是 Maven 项目,可以在 `pom.xml` 文件中添加...
包含翻译后的API文档:quartz-2.3.2-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.quartz-scheduler:quartz:2.3.2; 标签:quartz、scheduler、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用...
在这个系统中,Quartz作为核心的定时任务引擎,允许管理员动态创建、编辑、删除和修改定时任务。所有的任务配置信息,包括任务名称、执行时间、触发条件等,都可以存入数据库,便于集中管理和查询。 Swagger则是一...
这是一个基于Spring Boot、Apache Shiro、Spring MVC、MyBatis、Quartz和Druid的数据源管理框架的示例项目,名为"renren-security"。这个DEMO提供了完整的权限管理和任务调度解决方案,下面是这些技术栈的核心知识点...