`
sasunlin2000
  • 浏览: 14615 次
  • 性别: Icon_minigender_1
  • 来自: 河南省
社区版块
存档分类
最新评论

quartz工作调度

 
阅读更多
什么是动态定时任务:
是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现: cronExpression是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直接调用CronTriggerBean中设置cronExpression的方法,就可以顺利解决问题了。
① targetMethod: 指定需要定时执行scheduleInfoManager中的simpleJobTest()方法
② concurrent:对于相同的JobDetail,当指定多个Trigger时, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,多个job不会并发运行,第二个job将不会在第一个job完成之前开始。
③ cronExpression:0/10 * * * * ?表示每10秒执行一次,具体可参考附表。
④ triggers:通过再添加其他的ref元素可在list中放置多个触发器。scheduleInfoManager中的simpleJobTest()方法注意:此方法没有参数,如果scheduleInfoManager有两个方法simpleJobTest()和simpleJobTest(String argument),则spring只会去执行无参的simpleJobTest().
public void simpleJobTest()
{         
   log.warn("uh oh, Job is scheduled !'" + "' Success...");    
}
   Quartz在Spring中动态设置cronTrigger方法一Spring配置文件:
将定时器注入到业务逻辑层Manager

Xml代码 
01.<bean id="scheduleInfoManager" class="com.lively.happyoa.jobs.webapp.manager.scheduleInfoManager"> 
02.         <property name="scheduler" ref="schedulerFactory"/>  
03.     </bean>  
04.     <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
05.         <property name="targetObject" ref="scheduleInfoManager"/>  
06.         <property name="targetMethod" value="reScheduleJob"/>  
07.         <property name="concurrent" value="false"/>  
08.     </bean>  
09.     <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" >  
10.          <property name="jobDetail" ref="schedulerJobDetail"/>  
11.          <property name="cronExpression">  
12.              <value>0/10 * * * * ?</value>  
13.          </property>  
14.      </bean>  
15.     <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
16.         <property name="triggers">  
17.             <list>  
18.                 <ref local="cronTrigger"/>  
19.             </list>  
20.         </property>  
21.</bean> 

scheduleInfoManager中的reScheduleJob ()方法及相关方法① reScheduleJob读取数据库,获得自定义定时器调度时间():

Java代码 
01.private Scheduler scheduler;   
02. 
03.// 设值注入,通过setter方法传入被调用者的实例scheduler   
04.public void setScheduler(Scheduler scheduler) {      
05.     this.scheduler = scheduler;      
06.}     
07.rivate void reScheduleJob() throws SchedulerException,ParseException {   
08.        // 运行时可通过动态注入的scheduler得到trigger,注意采用这种注入方式在有的项目中会有问题,如果遇到注入问题,可以采取在运行方法时候,获得bean来避免错误发生。   
09.        CronTriggerBean trigger = (CronTriggerBean) scheduler.getTrigger(                "cronTrigger", Scheduler.DEFAULT_GROUP);   
10.        String dbCronExpression = getCronExpressionFromDB();  
11.        String originConExpression = trigger.getCronExpression();  
12.    // 判断从DB中取得的任务时间(dbCronExpression)和现在的quartz线程中的任务时间(originConExpression)是否相等   
13.    // 如果相等,则表示用户并没有重新设定数据库中的任务时间,这种情况不需要重新rescheduleJob   
14.        if(!originConExpression.equalsIgnoreCase(dbCronExpression)){   
15.            trigger.setCronExpression(dbCronExpression);  
16.            scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, trigger);   
17.        }  
18.    // 下面是具体的job内容,可自行设置   
19.    // executeJobDetail();} 

② getCronExpressionFromDB():从数据库中获得dbCronExpression的具体代码,由于使用了scheduleInfoManager,所以要在定义相应的setter方法:

Java代码 
01.private String getCronExpressionFromDB(){  
02.         String sql="from ScheduleInfo scheduleInfo where 1=1 ";   
03.         sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";   
04.         List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);  
05.         ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);   
06.         String dbCronExpression = scheduleInfo.getCronExpression();  
07.         return dbCronExpression;   
08.} 

③ 在spring配置文件的scheduleInfoManager配置了相应的property(scheduler/
Java代码 
01.scheduleInfoManager),要为其设置setter方法:   
02.private Scheduler scheduler;   
03.     // 设值注入,通过setter方法传入被调用者的实例scheduler   
04.     public void setScheduler(Scheduler scheduler) {   
05.         this.scheduler = scheduler;   
06.    }  
07.     private ScheduleInfoManager scheduleInfoManager;   
08.     // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager   
09.     public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){   
10.         this.scheduleInfoManager = scheduleInfoManager;   
11.     } 

Quartz在Spring中动态设置cronTrigger方法二在上面的2中我们可以看到,尽管已经可以动态进行rescheduleJob了,不过依然需要我们设置一个cronExpression,如果尝试一下拿掉spring配置中的        
<property name="cronExpression">
              <value>0/10 * * * * ?</value>
</property>
则容器(如tomcat)启动时会报错。实际中我们希望tomcat启动时就可以直接去读数据库,拿到相应的dbCronExpression,然后定时执行一个job,而不希望配置初始的cronExpression ,观察下面的CronTriggerBean,考虑到cronExpression需要初始化,如果设定一个类InitializingCronTrigger继承CronTriggerBean,然后在这个类中做一些读取DB的初始化工作(设置cronExpression),问题就可以解决了。Spring配置文件:

Xml代码 
01.<bean id="scheduleInfoManager" class="com.lively.happyoa.jobs.webapp.manager.ScheduleInfoManager">         <property name="scheduler" ref="schedulerFactory"/> 
02.     </bean>  
03.     <bean id="schedulerJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
04.         <property name="targetObject" ref="scheduleInfoManager"/>  
05.         <property name="targetMethod" value="reScheduleJob"/>  
06.         <property name="concurrent" value="false"/>  
07.     </bean>  
08.    <bean id="cronTrigger" class="com.lively.happyoa.jobs.webapp.manager.ScheduleInfoManager.InitializingCronTrigger">  
09.          <property name="jobDetail" ref="schedulerJobDetail"/>  
10.         <!--<property name="cronExpression">  
11.              <value>0/10 * * * * ?</value>  
12.          </property>-->  
13.         <property name="scheduleInfoManager" ref="scheduleInfoManager"/>  
14.      </bean>  
15.     <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
16.         <property name="triggers">  
17.             <list>  
18.                 <ref local="cronTrigger"/>  
19.             </list>  
20.         </property>  
21.</bean> 

InitializingCronTrigger中的相关方法注意:在注入scheduleInfoManager属性的时候,我们可以去读取DB任务时间(之所以放在setter方法中,是因为需要在设置scheduleInfoManager后进行getCronExpressionFromDB(),否则,也可以①②逻辑把放在类的构造函数中).注意InitializingCronTrigger必须extends CronTriggerBean.

Java代码 
01.public class InitializingCronTrigger extends CronTriggerBean implements Serializable {  
02.     private ScheduleInfoManager scheduleInfoManager;   
03.     // 设值注入,通过setter方法传入被调用者的实例scheduleInfoManager   
04.     public void setScheduleInfoManager(ScheduleInfoManager scheduleInfoManager){   
05.         this.scheduleInfoManager = scheduleInfoManager;   
06.         // 因为在getCronExpressionFromDB使用到了scheduleInfoManager,所以   
07.         // 必须上一行代码设置scheduleInfoManager后进行   
08.getCronExpressionFromDB  
09.         String cronExpression = getCronExpressionFromDB ();  
10.    // ①   
11.         // 因为extends CronTriggerBean ,此处调用父类方法初始化cronExpression   
12.        setCronExpression(cronExpression);  
13.                     // ②}   
14.     private String getCronExpressionFromDB(){   
15.         String sql="from ScheduleInfo scheduleInfo where  
16. 1=1 ";   
17.         sql=sql+" and scheduleInfo.infoId = '"+"1" + "'";   
18.         List scheduleList = scheduleInfoManager.queryScheduleInListBySql(sql);  
19.         ScheduleInfo scheduleInfo = (ScheduleInfo)scheduleList.get(0);   
20.         String dbCronExpression = scheduleInfo.getCronExpression();  
21.         return dbCronExpression;}……} 
Quartz中时间参数说明 即Cron表达式
Cron表达式
Quartz使用类似于Linux下的Cron表达式定义时间规则,Cron表达式由6或7个由空格分隔的时间字段组成,如表1所示:

表1 Cron表达式时间字段

位置
 
时间域名 允许值 允许的特殊字符
 
 
 
1 秒 0-59 , - * /
 
2 分钟 0-59 , - * /
 
3 小时 0-23 , - * /
 
4 日期 1-31 , - * ? / L W C
 
5 月份 1-12 , - * /
 
6 星期 1-7 , - * ? / L C #
 
7 年(可选) 空值1970-2099 , - * /


Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能,细说如下:

●星号(*):可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示“每分钟”;

●问号(?):该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符;

●减号(-):表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12;

●逗号(,):表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五;

●斜杠(/):x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y;

●L:该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五;

●W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围;

●LW组合:在日期字段可以组合使用LW,它的意思是当月的最后一个工作日;

●井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发;

● C:该字符只在日期和星期字段中使用,代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。

Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

表2下面给出一些完整的Cron表示式的实例:

表2 Cron表示式示例

表示式
说明
 
 
"0 0 12 * * ? " 每天12点运行
 
"0 15 10 ? * *" 每天10:15运行
 
"0 15 10 * * ?" 每天10:15运行
 
"0 15 10 * * ? *" 每天10:15运行
 
"0 15 10 * * ? 2008" 在2008年的每天10:15运行
 
"0 * 14 * * ?" 每天14点到15点之间每分钟运行一次,开始于14:00,结束于14:59。
 
"0 0/5 14 * * ?" 每天14点到15点每5分钟运行一次,开始于14:00,结束于14:55。
 
"0 0/5 14,18 * * ?" 每天14点到15点每5分钟运行一次,此外每天18点到19点每5钟也运行一次。
 
"0 0-5 14 * * ?" 每天14:00点到14:05,每分钟运行一次。
 
"0 10,44 14 ? 3 WED" 3月每周三的14:10分到14:44,每分钟运行一次。
 
"0 15 10 ? * MON-FRI" 每周一,二,三,四,五的10:15分运行。
 
"0 15 10 15 * ?" 每月15日10:15分运行。
 
"0 15 10 L * ?" 每月最后一天10:15分运行。
 
"0 15 10 ? * 6L" 每月最后一个星期五10:15分运行。
 
"0 15 10 ? * 6L 2007-2009" 在2007,2008,2009年每个月的最后一个星期五的10:15分运行。
 
"0 15 10 ? * 6#3" 每月第三个星期五的10:15分运行。
 
 


注意:CronTriggerBean的cronExpression属性指定格式:至少6个时间元素,上面表示每天的15:37-38分执行1次任务。

时间元素(按照顺序):

秒(0-59):

分(0-59):

小时(0-23):

每月第几天(1-31):

月(1-12或JAN-DEC):

每星期第几天(1-7或SUN-SAT):

年(1970-2099):

其中:不用设置的用”?”.

(1)每月第几天和每星期第几天是互斥的,两个只能设置1个。如果有好几个时间点,可以使用”,”符号,例如:”0 0 10,12,14 * * ?”表示每天的10时,12时,14时执行Job.

(2)对于连续时间可以使用”-”符号。例如:”0 10,12,14 1-15 * ?”表示每月的1到15日10时,12时,14时执行Job.

(3)时间格式的年可以不用制定。例如”0 0 10,12,14 ? MON 2006”表示2006年每星期一的10时,12时,14时执行Job.

分享到:
评论

相关推荐

    quartz工作原理

    quartz工作原理

    Quartz任务调度管理

    #### 四、Quartz工作原理详解 Quartz的工作流程如下: 1. **任务定义**:首先定义具体的任务,即定义`Job`类。例如,创建一个实现`org.quartz.Job`接口的类`RemindJob`,并在其中定义执行逻辑。 ```java public ...

    quartz quartz-1.8.6 dbTables 建表sql

    Quartz 是一个开源的作业调度框架,广泛应用于Java应用程序中,用于执行定时任务。它提供了丰富的API和灵活性,使得开发者可以方便地定义、安排和管理各种任务。版本1.8.6是Quartz的一个稳定版本,它包含了对数据库...

    quartz-1.6.0.jar和quartz-all-1.6.0.jar

    Quartz是Java领域的一款强大的开源任务调度框架,它允许开发者创建和管理定时任务,从而实现应用程序的自动执行功能。在给定的压缩包文件中,我们有两个版本为1.6.0的Quartz JAR包:`quartz-1.6.0.jar`和`quartz-all...

    quartz-2.2.3版本的quartz初始化sql语句

    Quartz是一款广泛使用的开源任务调度框架,它允许开发者在Java应用程序中定义和执行定时任务。在Quartz 2.2.3版本中,初始化数据库是使用Quartz的关键步骤,因为Quartz依赖于一个持久化存储来保存作业和触发器的信息...

    quartz实例,quartz入门例子

    1. **Job**:工作,它是实际要执行的任务,可以定义一个Java类实现`org.quartz.Job`接口来创建Job。 2. **Trigger**:触发器,决定Job何时执行。Quartz提供了多种类型的Trigger,如SimpleTrigger(简单触发器)和...

    quartz创建表sql

    Quartz 是一个开源的作业调度框架,广泛应用于Java企业级应用中,用于自动化任务执行,如定时触发工作流、发送邮件、数据同步等。在Quartz的部署和配置过程中,为了存储作业和触发器的信息,我们需要在关系型数据库...

    quartz_2.3.0 SQL脚本

    这些脚本包含了创建Quartz所需的所有表和视图,使得Quartz可以在这些数据库系统中正常工作。 1. **Oracle数据库脚本** (`tables_oracle.sql`): Oracle是关系型数据库管理系统之一,以其高性能和企业级特性著名。...

    Quartz 线程池

    本文将深入探讨 Quartz 线程池的工作原理、配置以及如何在实际项目中应用。 ### 一、Quartz 线程池的基本概念 线程池是计算机科学中的一个概念,主要用于管理多个并发运行的线程。在 Quartz 中,线程池负责处理由 ...

    Quartz 批量下载源码

    Quartz 批量下载源码,Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码Quartz 批量下载源码

    quartz scheduler 入门教程

    quartz scheduler 入门教程 Quartz Scheduler 是一种功能丰富、开源的任务调度程序库,可以在任何 Java 程序中使用。它可以用来创建简单或者复杂的执行次数可以达成千上万的任务。任务可以是任何 Java 可以做的事情...

    Android studio下的quartz工程

    **Android Studio下的Quartz工程详解** Quartz是一个开源的作业调度框架,广泛应用于Java环境中的任务调度。在Android Studio中使用Quartz,可以为应用程序添加定时执行的任务功能,例如定期发送通知、更新数据或者...

    Quartz所需jar包

    2. **定义Job**:`Job`是你要执行的任务的抽象,你需要创建一个实现`org.quartz.Job`接口的类,并重写`execute`方法来定义具体的工作逻辑。 3. **创建JobDetail**:使用`JobDetail`来实例化你的`Job`,设置其名称和...

    Quartz调度、终止执行的任务

    Quartz是一款开源的作业调度框架,它允许开发者创建和安排任务执行。在Java应用程序中,Quartz能够帮助我们在特定的时间点或按照预设的周期执行某些...在实际开发中,理解并熟练运用Quartz将极大地提升我们的工作效率。

    Quartz.NET 官方源码及演示例子

    7. **src**:源代码目录,包含Quartz.NET的源码,开发者可以查看和学习其内部工作原理。 8. **lib**:库文件夹,可能包含Quartz.NET依赖的外部库。 9. **doc**:文档目录,可能有API参考、用户指南等帮助材料。 *...

    quartz-2.3.2-API文档-中文版.zip

    赠送jar包:quartz-2.3.2.jar; 赠送原API文档:quartz-2.3.2-javadoc.jar; 赠送源代码:quartz-2.3.2-sources.jar; 赠送Maven依赖信息文件:quartz-2.3.2.pom; 包含翻译后的API文档:quartz-2.3.2-javadoc-API...

    quartz和spring-quartz

    Quartz和Spring-Quartz是两个在Java世界中广泛使用的定时任务管理框架。Quartz是一个开源的作业调度框架,允许应用程序定义和调度任务在特定时间执行。而Spring-Quartz则是Spring框架对Quartz的集成,它使得在Spring...

    深入解读Quartz的原理

    它是 Quartz 中最基本的工作单元。`Job` 接口定义了一个唯一的方法 `void execute(JobExecutionContext context)`,该方法包含实际要执行的业务逻辑。 2. **JobDetail**:表示一个具体的可执行的调度程序。`...

    quartz官方数据库大全

    Quartz是一个功能丰富的开源作业调度库,几乎可以集成在任何Java应用程序中 - 从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数十,数百甚至数万个作业; 将任务定义为标准...

    quartz.jar包下载

    Quartz.jar是一个非常重要的Java库,它主要用于计划和执行任务,特别是在企业级应用程序中。这个包包含了一系列的类和接口,使得开发者能够方便地...正确理解和使用Quartz,能极大地提高你的工作效率并优化系统运行。

Global site tag (gtag.js) - Google Analytics