Spring的Quartz使用说明

时间:2021-11-21 05:07:45

集成起来比较简单,对线程无需任何理解,Spring手册上也有清楚的说明。

只需写一个POJO,其余的都是配置,而且若使用CronTriggerBean,可以配置很复杂的任务调度。


1.编写一个普通的JAVA类

package com.spring.quartz;

public class SpringQuartDemo {
	public void doHappy(){
		System.out.println("Happy! ");
	}
	public void doHello(){
		System.out.println("Hello!");
	}
}


2. 配置springQuartz.xml

springQuartz.xml

<?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:tx="http://www.springframework.org/schema/tx"  
          xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
  
        <bean id="springQuartDemo" class="com.spring.quartz.SpringQuartDemo"></bean>
    
        <bean id="obtainMetricMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
	    <property name="targetObject" ref="springQuartDemo" />
	    <property name="targetMethod" value="doHello" />
	    <!-- 并发执行 -->
	    <property name="concurrent" value="true" />
	</bean>
	<bean id="obtainMetricTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
	    <property name="jobDetail" ref="obtainMetricMethod"></property>
	    <property name="cronExpression" value="0 */1 * * * ?"></property>
	</bean>
	
        <!-- ======================== 调度工厂 ======================== -->
	<bean id="springJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	    <property name="startupDelay" value="10" />
	    <property name="triggers">
	        <list>
	            <ref bean="obtainMetricTrigger"/>
	        </list>  
	    </property>  
	</bean>
</beans>  


说明:

使用MethodInvokingJobDetailFactoryBean建立任务

targetObject 目标对象,即需要定时执行的POJO
targetMethod 目标方法,即需要定时执行的POJO方法
concurrent 默认情况下,Quartz Jobs是无状态的,可能导致jobs之间互相的影响,如果你为相同的JobDetail指定两个Trigger,很可能当第一个job完成之前,第二个job就开始了。如果Jobdetail实现了Stateful接口,就不会发生这样的事情。第二个job将不会在第一个job完成之前开始。为了使得jobs不并发运行,设置concurrent标记为false


使用CronTriggerBean建立规则,调度任务

jobDetail 任务详情,即所需要调度的任务
cronExpression 调用规则,即什么时候调用。详细说明见附录


使用SchedulerFactoryBean包装任务

triggers 触发器,调用哪些任务
autoStartup 是否自动启动,该Bean被初始化后是否自动启动定时任务
schedulerName 给这个计划设定一个名称。


3. 配置web.xml

web.xml文件中配置,加载springQuartz.xml

     <!-- 初始化 -->  
     <context-param>  
         <param-name>contextConfigLocation</param-name>  
         <!-- 如果有多个文件,在文件之间用英文逗号隔开 -->  
         <param-value>classpath:spring.xml;classpath:modules/**/spring*.xml</param-value>  
     </context-param>


4.附录

Spring--quartz中cronExpression

 
字段 允许值 允许的特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日期 1-31 , - * ? / L W C
月份 1-12 或者 JAN-DEC , - * /
星期 1-7 或者 SUN-SAT , - * ? / L C #
年(可选) 留空, 1970-2099 , - * /


通配符(*)可以用来表示某个子表达式域的每一个可能的值。因此,“*”号用在月份里,表示每月。用在星期几里,表示一周中的每天。

每个 子表达式域都有一组有效的值,这些值都是显然意见的。例:用0-59表示秒和分,用0到23表示小时。几号用0-31中的任何值,但是要小心每月的天数。 月份指定的值应该是0至11,也可以用字符串 JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV和DEC表示。星期几用1到7表示(1=星期天),或用英文字 符表示:SUN,MON,TUE,WED,THU,FRI和SAT。

字符“/”用来表示增量的值。例如:如果用“0/15”表示分,就表 示从一个小时的0分开始,在这小时内每隔15分钟一次。如果用"3/20"表示分,则表示从一个小时的3分开始,在这小时内每隔20分钟一次。也可以用 “3,23,43”表示。注意"*/35"并不是表示每35分钟,而是表示从一个小时的0分开始,每隔35分钟一次,相当于"0,35"。

“?"号允许用在几号和星期几的子字符串域中,用来说明没有指定值。

“L” 字符允许用在几号和星期几域中,是"last"的缩写。“L”用在几号里意思是这个月的最后一天,如果是1月就指31号,如果是闰年的2月就是28号。如 果用在星期几里,他就是表示“7”或者“SAT”(星期六)。但是如果L用在一个值的后面联合表示星期几域,就表示“这个月最后一个星期几”。例 如:“6L”或“FRIL”表示这个月的最后一个星期五。同样也可以用一个偏移变量表示距离某个月最后一天的天数。例如:“L-3”表示某月最后一天的倒 数第三天。但用“L“字符时,不要将“L”用在列表或范围中,那样你会混淆或者获得不是预期的结果。

“W”用来指定某一号最近的工作日(星期一至五),例如:“15W”放在几号里,表示这个月15号最近的一个工作日。


“#”号用指定某月第几个工作日,例如:“6#3”或“FRI#3”放在星期几域中,表示这个月第三个星期五。


例子

表达式意义
"0 0 12 * * ?" 每天中午12点触发
"0 15 10 ? * *" 每天上午10:15触发
"0 15 10 * * ?" 每天上午10:15触发
"0 15 10 * * ? *" 每天上午10:15触发
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2: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 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发

每天早上6点
0 6 * * *
每两个小时
0 */2 * * *
晚上11点到早上8点之间每两个小时,早上八点
0 23-7/2,8 * * *
每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3
1月1日早上4点
0 4 1 1 *

例如:"0 0 12 ? * WED"-表示每周三12:00:00pm"。

其中每个独立的子表达式都可以用范围或者列表表示。例如:

前例的”WED“也可以写成:

"MON-FRI"(范围表示)

"MON,WED,FRI"(列表表示)

"MON-WED,SAT"(范围加列表)



下面是一些表达式的样例,你可以从JavaDoc中找到更多的例子。

Cron Expressions示例

例1-一个表达式表示每5分钟。

"0 0/5 * * * ?"

例2——表示每分钟的10秒后,每5钟一次(如:10:00:10 am,10:05:10 am,等等)

"10 0/5 * * * ?"

例3——表示运行在每个星期三,星期五的10:30,11:30,12:30 and 13:30

"0 30 10-13 ? * WED,FRI"

例4——表示每月的5号和20号的早8点至早10点每30分钟一次。

"0 0/30 8-10 5,20 * ?"

注意,有些计划调度需求如果用一个触发器会很复杂,例如:“早9:00至10:00每5分钟,下午1:00至10:00每20分钟”,这种情况下可以是单的创建两个触发器同时运行一个JOB