Quartz 是开源任务调度框架中的翘首,它提供了强大任务调度机制,同时保持了使用的简单性。
Quartz 允许开发人员灵活地定义触发器的调度时间表,并可以对触发器和任务进行关联映射。
此外,Quartz提供了调度运行环境的持久化机制,可以保存并恢复调度现场,即使系统因故障关闭,任务调度现场数据并不会丢失。
此外,Quartz还提供了组件式的侦听器、各种插件、线程池等功能。
Spring中使用Quartz的3种方法(MethodInvokingJobDetailFactoryBean,implements Job,extends QuartzJobBean)
以下介绍一下实现job接口的方法,通过此方法可以动态启动,暂定,添加,删除定时功能,可传参数。
所有数据全部持久化到数据表中,不再需要XML配置文件存储数据。quartz已经封装了持久化方法。数据表用的MYSQL见附件
package com.berheley.bi.basic.timer; import java.util.Map; import org.quartz.JobExecutionContext; import com.berheley.bi.basic.exp.BusinessException; /** * 类功能描述:定时任务需要实现此接口 * * @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a> * Create: 2010-1-3 上午09:18:51 * Description: */ public interface ITimerJob { /** * 定时器执行的任务 * @param context * @throws Exception */ void jtaTimerExecute(JobExecutionContext context, Map<?, ?> parameters)throws BusinessException; } package com.berheley.bi.basic.timer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.webframe.web.util.WebFrameUtils; import com.berheley.bi.basic.exp.BusinessException; /** * 类功能描述:定时执行的任务,发布表单 * * @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a> * Create: 2009-12-31 上午12:31:02 * Description: */ public class TimerDataJob implements Job { private ITimerJob timerJob; protected Log log = LogFactory.getLog(getClass()); @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap parameters = context.getJobDetail().getJobDataMap(); try { Object beanName = parameters.get("beanName"); if (beanName == null) { log.error("JobDataMap 中'beanName'属性值为null!"); return; } timerJob = (ITimerJob) WebFrameUtils.getBean(beanName.toString()); timerJob.jtaTimerExecute(context, parameters); } catch (NoSuchBeanDefinitionException e) { log.error("任务ITimerJob接口的实现类(" + e.getBeanName() + ")不存在!"); } catch (BusinessException e) { log.error(e.getMessage(), e); } } } import java.util.Map; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.Trigger; import com.berheley.bi.basic.exp.BusinessException; /** * 类功能描述:定时调度后台管理 * * @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a> Create: 2010-1-3 上午09:18:51 * Description: */ public interface ITimerManageService { /** * 获得scheduler */ Scheduler getScheduler(); /** * * @function:获得任务 * @param jobName * @param jobGroup * @return * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:29:03 */ JobDetail getJob(String jobName, String jobGroup) throws BusinessException; /** * * @function:添加任务 * @param jobDetail * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:29:15 */ void addJob(JobDetail jobDetail) throws BusinessException; /** * * @function:删除任务 * @param jobName * @param jobGroup * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:29:31 */ void deleteJob(String jobName, String jobGroup) throws BusinessException; /** * * @function:立即运行 * @param jobName * @param jobGroup * @author: mengqingyu 2012-5-24 上午11:00:20 */ void addRunNowTrigger(String jobName, String jobGroup) throws BusinessException ; /** * * @function:重置定时器 * @param jobName * @param jobGroup * @param trigger * @throws BusinessException * @author: mengqingyu 2012-11-30 下午05:22:48 */ public void rescheduleJob(String triggerName, String triggerGroup, Trigger trigger) throws BusinessException; /** * * @function:获得定时器 * @param jobName * @param jobGroup * @return * @throws BusinessException * @author: mengqingyu 2012-11-30 下午05:17:09 */ Trigger getTrigger(String jobName, String jobGroup) throws BusinessException; /** * * @function:添加定时 * @param trigger * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:29:41 */ void addTrigger(Trigger trigger) throws BusinessException; /** * 删除定时 * * @param triggerName * @param group */ void deleteTrigger(String triggerName, String group) throws BusinessException ; /** * 暂停定时 * * @param triggerName * @param group */ void updatePauseTrigger(String triggerName, String group) throws BusinessException ; /** * 恢复Trigger * * @param triggerName * @param group */ void updateResumeTrigger(String triggerName, String group) throws BusinessException ; /** * * @function:保存、修改任务 * @param jobName * @param jobGroup * @param description * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:32:35 */ void saveOrUpdateJob(String jobName, String jobGroup, String description) throws BusinessException; /** * * @function:批量删除任务 * @param jobNames * @param jobGroup * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:33:11 */ void deleteJobs(String jobNames, String jobGroup) throws BusinessException; /** * * @function:查询任务参数 * @param jobName * @param jobGroup * @return * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:34:20 */ String findJobParams(String jobName, String jobGroup) throws BusinessException; /** * * @function:保存任务参数 * @param jobName * @param jobGroup * @param key * @param value * @return * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:38:17 */ String saveJobParam(String jobName, String jobGroup, String key, String value) throws BusinessException; /** * * @function:删除任务参数 * @param jobName * @param jobGroup * @param keys * @return * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:38:26 */ String deleteJobParams(String jobName, String jobGroup, String keys) throws BusinessException; /** * * @function:保存cron * @param params * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:38:41 */ void saveCron(Map<String, Object> params) throws BusinessException; /** * * @function:保存simple * @param params * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:40:39 */ void saveSimple(Map<String, Object> params) throws BusinessException; /** * * @function:批量删除定时 * @param jobName * @param group * @param triggerNames * @throws BusinessException * @author: mengqingyu 2012-10-22 下午03:41:42 */ void deleteTriggers(String jobName, String group, String triggerNames) throws BusinessException; /** * 根据名称和组别启动和暂停Tigger * * @param triggerName * @param group */ String updateStartOrStop(String jobName, String jobGroup) throws BusinessException ; } import java.text.ParseException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.quartz.CronTrigger; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.webframe.core.util.DateUtils; import com.berheley.bi.basic.exp.BusinessException; import com.berheley.bi.basic.util.UUIDGenerator; /** * 类功能描述:通用定时功能 * * @author <a href="mailto:qingyu.meng21@gmail.com">mengqingyu </a> * @version $Id: codetemplates.xml,v 1.1 2009/03/06 01:13:01 mengqingyu Exp $ Create: 2011-6-1 * 下午05:03:06 */ @Service public class TimerManageService implements ITimerManageService { @Autowired protected Scheduler scheduler; public Scheduler getScheduler() { return scheduler; } @Override public JobDetail getJob(String jobName, String jobGroup) throws BusinessException{ JobDetail jobDetail; try { jobDetail = scheduler.getJobDetail(jobName, jobGroup); } catch (SchedulerException e) { throw new BusinessException("获取任务失败", e); } return jobDetail; } @Override public void addJob(JobDetail jobDetail) throws BusinessException{ try { scheduler.addJob(jobDetail, true); } catch (SchedulerException e) { throw new BusinessException("添加任务失败", e); } } @Override public void deleteJob(String jobName, String jobGroup) throws BusinessException{ try { scheduler.deleteJob(jobName, jobGroup); } catch (SchedulerException e) { throw new BusinessException("删除任务失败", e); } } @Override public void addRunNowTrigger(String jobName, String jobGroup) throws BusinessException{ try { scheduler.triggerJob(jobName, jobGroup); } catch (SchedulerException e) { throw new BusinessException("立即运行任务失败", e); } } @Override public void rescheduleJob(String triggerName, String triggerGroup, Trigger trigger) throws BusinessException{ try { scheduler.rescheduleJob(triggerName,triggerGroup,trigger); } catch (SchedulerException e) { throw new BusinessException("重置定时器失败", e); } } @Override public Trigger getTrigger(String triggerName, String triggerGroup) throws BusinessException{ Trigger trigger; try { trigger = scheduler.getTrigger(triggerName,triggerGroup); } catch (SchedulerException e) { throw new BusinessException("获取定时器失败", e); } return trigger; } @Override public void addTrigger(Trigger trigger) throws BusinessException { try { trigger.setVolatility(false); scheduler.scheduleJob(trigger); } catch (SchedulerException e) { throw new BusinessException("添加定时器失败", e); } } @Override public void deleteTrigger(String triggerName, String group) throws BusinessException{ this.updatePauseTrigger(triggerName, group); try { scheduler.unscheduleJob(triggerName, group); } catch (SchedulerException e) { throw new BusinessException("删除定时任务失败", e); } } @Override public void updatePauseTrigger(String triggerName, String group) throws BusinessException{ try { scheduler.pauseTrigger(triggerName, group); } catch (SchedulerException e) { throw new BusinessException("停止定时任务失败", e); } } @Override public void updateResumeTrigger(String triggerName, String group) throws BusinessException{ try { scheduler.resumeTrigger(triggerName, group); } catch (SchedulerException e) { throw new BusinessException("恢复定时任务失败", e); } } @Override public void saveOrUpdateJob(String jobName, String jobGroup, String description) throws BusinessException { JobDetail jobDetail; if(StringUtils.isBlank(jobName)){ jobName = UUIDGenerator.getUUID(); try { jobDetail = new JobDetail(jobName, jobGroup, Class.forName("com.berheley.bi.basic.timer.TimerDataJob")); } catch (ClassNotFoundException e) { throw new BusinessException("添加修改任务失败", e); } } else { jobDetail = this.getJob(jobName, jobGroup); } jobDetail.setDescription(description); this.addJob(jobDetail); } @Override public void deleteJobs(String jobNames, String group) throws BusinessException { String[] jobs = jobNames.split(","); String[] groups = group.split(","); for(int i=0;i<jobs.length;i++){ this.deleteJob(jobs[i], groups[i]); } } public String paramMapToList(JobDataMap params) { ArrayList<List<String>> listJobData = new ArrayList<List<String>>(); for (Object e: params.entrySet()) { Map.Entry<?, ?> entry = (Entry<?, ?>) e; ArrayList<String> list = new ArrayList<String>(); list.add("'" + entry.getKey() + "'"); list.add("'" + entry.getValue() + "'"); listJobData.add(list); } return listJobData.toString(); } @Override public String findJobParams(String jobName, String jobGroup) throws BusinessException { JobDetail jobDetail = this.getJob(jobName, jobGroup); return jobDetail == null?"{}":paramMapToList(jobDetail.getJobDataMap()); } @Override public String saveJobParam(String jobName, String jobGroup, String key, String value) throws BusinessException { JobDetail jobDetail = this.getJob(jobName, jobGroup); JobDataMap params = jobDetail.getJobDataMap(); params.put(key, value); this.addJob(jobDetail); return paramMapToList(params); } @Override public String deleteJobParams(String jobName, String jobGroup, String keys) throws BusinessException { JobDetail jobDetail = this.getJob(jobName, jobGroup); JobDataMap params = jobDetail.getJobDataMap(); String[] key = keys.split(","); for(int i=0;i<key.length;i++){ params.remove(key[i]); } this.addJob(jobDetail); return paramMapToList(params); } public void initTrigger(Trigger trigger, Map<String, Object> params) { trigger.setDescription(params.get("label").toString()); trigger.setJobName(params.get("jobName").toString()); trigger.setJobGroup(params.get("group").toString()); String startTime = params.get("startTime")==null?"":params.get("startTime").toString(); String stopTime = params.get("stopTime")==null?"":params.get("stopTime").toString(); if (!StringUtils.isBlank(startTime)) { trigger.setStartTime(DateUtils.parseStringToDate(startTime,"yyyy-MM-dd HH:mm:ss")); } if (!StringUtils.isBlank(stopTime)) { trigger.setEndTime(DateUtils.parseStringToDate(stopTime,"yyyy-MM-dd HH:mm:ss")); } } @Override public void saveCron(Map<String, Object> params) throws BusinessException { Trigger trigger = null; try { trigger = new CronTrigger(UUIDGenerator.getUUID(), params.get("group").toString(), params.get("cronExpression").toString()); } catch (ParseException e) { throw new BusinessException("添加cron失败", e); } this.initTrigger(trigger, params); this.addTrigger(trigger); } @Override public void saveSimple(Map<String, Object> params) throws BusinessException { String countStr = params.get("repeatCount").toString(); int repeatCount = countStr.equals("")?SimpleTrigger.REPEAT_INDEFINITELY:Integer.parseInt(countStr); long repeatInterval = Long.parseLong(params.get("repeatInterval").toString()); Trigger trigger = new SimpleTrigger(UUIDGenerator.getUUID(), params.get("group").toString(), repeatCount, repeatInterval); this.initTrigger(trigger, params); this.addTrigger(trigger); } @Override public void deleteTriggers(String jobName, String group, String triggerNames) throws BusinessException { String[] trigger = triggerNames.split(","); for(int i=0;i<trigger.length;i++){ this.deleteTrigger(trigger[i], group); } } @Override public String updateStartOrStop(String triggerName, String group) throws BusinessException { int flag = -1; try { flag = scheduler.getTriggerState(triggerName,group); switch (flag) { case 0 : scheduler.pauseTrigger(triggerName, group); flag = 1; break; case 1 : scheduler.resumeTrigger(triggerName, group); flag = 0; break; } } catch (SchedulerException e) { throw new BusinessException("修改定时状态失败", e); } return "{state:'"+flag+"'}"; } }
这种配置就是对quartz的一种简单的使用了,调度任务会在spring启动的时候加载到内存中,按照bjcronTrigger中定义的crontrigger定义的时间按时触发调度任务。
但是这是quartz使用“内存”方式的一种配置,也比较常见,当然对于不使用spring的项目,也可以单独整合quartz。
方法也比较简单,可以从quartz的doc中找到配置方式,或者看一下《Quartz Job Scheduling Framework 》(附件中可下载)这本书中的例子。
但是对于想持久化调度任务的状态,并且灵活调整调度时间的方式来说,上面的内存方式就不能满足要求了,正如本文开始我遇到的情况,需要采用数据库方式集成quartz,
这部分集成其实在《Quartz Job Scheduling Framework 》中也有较为详细的介绍,当然doc文档中也有,
但是缺乏和spring集成的实例,我在这里把我在项目中在spring配置quartz数据库存储方式的配置也写一下:
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="applicationContextSchedulerContextKey" value="BI-Scheduler" /> <property name="configLocation" value="classpath:quartz.properties" /> </bean> </beans>
属性说明:
dataSource:项目中用到的数据源,里面包含了quartz用到的12张数据库表;
schedulerName:调度器名,我理解主要在调度集群的时候会有用,如果出现多个调度器实例的时候可以用来进行区分,详细看一下《Quartz Job Scheduling Framework 》;
configLocation:用于指明quartz的配置文件的位置,如果不用spring配置quartz的话,本身quartz是通过一个配置文件进行配置的
,默认名称是quartz.properties,里面配置的参数在quartz的doc文档中都有介绍,可以调整quartz,我在项目中也用这个文件部分的配置了一些属性,代码如下:
#============================================================================ # Configure Main Scheduler Properties #============================================================================ org.quartz.scheduler.instanceName = TestScheduler org.quartz.scheduler.instanceId = AUTO #============================================================================ # Configure ThreadPool #============================================================================ org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 5 org.quartz.threadPool.threadPriority = 4 #============================================================================ # Configure JobStore #============================================================================ org.quartz.jobStore.misfireThreshold = 60000 #org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX ##org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.OracleDelegate #org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate #org.quartz.jobStore.dataSource = myDS org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = false #============================================================================ # Configure Plugins #============================================================================ org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingJobHistoryPlugin #org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin # init plugin will load jobs.xml as a classpath resource i.e. /jobs.xml if not found on file system #org.quartz.plugin.jobInitializer.fileName=jobs.xml #org.quartz.plugin.jobInitializer.overWriteExistingJobs = false #org.quartz.plugin.jobInitializer.failOnFileNotFound = false
相关推荐
在本文中,我们将详细介绍如何将 Spring 整合任务调度框架 Quartz,从而实现任务调度的自动化。 一、使用配置文件方式整合 Quartz 在 Spring 中,可以使用配置文件方式来整合 Quartz。这种方式非常简单,开发者只...
Spring框架作为Java领域广泛使用的轻量级框架,提供了与第三方库Quartz的整合,使得开发者能够轻松地在Spring应用中实现复杂的定时任务调度。Quartz是一款开源的作业调度框架,支持丰富的调度策略,可以满足各种定时...
3. **整合过程**:整合 Spring 2 和 Quartz 需要在 Spring 配置文件中声明 Job 和 Trigger 的 Bean,并指定它们的关联。Spring 可以通过其自身的 JobFactory 来创建 Job 实例,使得 Job 可以利用 Spring 的 DI 功能...
Spring整合Quartz 2.2.3是...总之,Spring与Quartz的整合使得我们能够便捷地在Spring应用中实现复杂的定时任务管理。通过深入理解Quartz的工作原理和Spring的整合机制,开发者可以更好地控制和扩展应用的定时任务功能。
在Spring中整合Quartz,我们可以利用Spring的管理能力,如bean的生命周期管理和事务管理,来更方便地创建和管理定时任务。 **Spring+Quartz动态定时任务创建** 将Spring与Quartz结合,我们可以方便地在运行时动态...
将Quartz与Spring整合,可以方便地管理和控制定时任务,同时利用Spring的依赖注入和管理功能,提高代码的可维护性和可测试性。 Quartz的核心概念包括Job、Trigger和Scheduler。Job是实际需要执行的任务,Trigger是...
Spring整合Quartz是一个常见的任务调度解决方案,用于在Java应用程序中执行定时任务。Quartz是一个功能丰富的开源作业调度框架,而Spring则是一个强大的企业级应用开发框架。将两者结合,可以方便地在Spring管理的...
在Java Spring中整合Quartz,可以利用Spring的管理能力来控制Quartz的作业和触发器,使得整个系统更加灵活和易于维护。以下将详细介绍如何进行Spring与Quartz的整合。 1. **集成步骤** - 添加依赖:首先,确保在...
Quartz可以集成到Spring中,利用Spring的依赖注入和配置能力,使得任务调度更加简洁和易于维护。 **一、Spring与Quartz的集成** 1. **配置Quartz** 在Spring应用中集成Quartz,首先需要添加Quartz的相关依赖到...
在Spring中,我们可以通过实现`org.springframework.scheduling.quartz.JobDetailBean`和`org.springframework.scheduling.quartz.CronTriggerBean`,将它们作为Spring Bean进行管理。 3. **动态调度**:通过Spring...
Spring Quartz 是一个强大的任务调度框架,它允许开发者在Java应用程序中定义和执行定时任务。结合Spring框架,可以方便地在企业级应用中实现复杂的时间触发逻辑。本实例提供了可以直接运行的任务调度解决方案,既...
在IT行业中,构建高效、可扩展的Web应用是至关重要的,而"spring+springMVC+mybatis+quartz动态定时任务创建"就是一个常见的技术栈,用于实现这样的目标。这个组合充分利用了各组件的优势,提供了强大的后端服务支持...
在 Spring 框架中,Quartz 是一个非常流行的开源作业调度器,可以实现任务的定时执行。在本篇文章中,我们将讨论如何在 Spring 中配置 Quartz,以实现 Java 定时器的功能。 Quartz 介绍 Quartz 是一个开源的作业...
本示例将探讨如何将 Spring 3 与 Quartz 1.8 和 2.2 版本进行整合,以实现高效的任务调度。 首先,我们来看 Spring 3 整合 Quartz 1.8 的步骤: 1. **引入依赖**:在项目中添加 Quartz 和 Spring 相关的库,确保...
Quartz是一款功能强大的开源作业调度框架,常用于在Java应用中执行定时任务。Spring则是一个广泛应用的IoC(控制反转)和AOP(面向切面编程)容器,它提供了丰富的功能来管理Bean以及整个应用程序的生命周期。将...
在Spring整合Quartz的过程中,首先需要在Spring配置文件中声明Scheduler工厂bean,然后定义Job和Trigger的bean。Spring通过`org.springframework.scheduling.quartz.SchedulerFactoryBean`来创建和管理Quartz的...
在IT行业中,Spring框架与Quartz的整合是一个常见的任务调度解决方案。这个压缩包文件提供了一个实际的示例,用于演示如何在Spring应用中集成Quartz进行任务调度。下面将详细解释其中涉及的知识点。 首先,Quartz是...
《Spring任务调度配置详解:Spring+Quartz的整合应用》 在Java开发中,任务调度是不可或缺的一部分,Spring框架提供了与Quartz集成的能力,使得我们可以方便地管理和执行定时任务。本文将详细介绍如何通过Spring和...
另外,Spring还提供了`MethodInvokingJobDetailFactoryBean`,它可以直接将Spring容器中的Bean的方法转换为Quartz任务,无需为Job创建单独的类。这对于那些希望直接利用现有业务服务进行调度的开发者来说非常方便。 ...