Spring 与Quartz实现定时任务调度
Spring 与Quartz实现定时任务调度
这两天,组长让我实现定时运行程序的功能,刚开始一头雾水,后来慢慢清晰了,利用Quartz就可以实现了!
首先,需要一些重要的包:
quartz-1.8.5.jar
commons-logging.jar
spring-batch-core-3.0.5.RELEASE.jar
其他的包就不说了。在此要说明,如果用spring3.0,则必须用quartz2以下的版本,否则会发生如下冲突:
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [org.springframework.scheduling.quartz.CronTriggerBean] for bean with name 'mytrigger' defined in class path resource [applicationContext.xml]: problem with class file or dependent class; nested exception is java.lang.IncompatibleClassChangeError: class org.springframework.scheduling.quartz.CronTriggerBean has interface org.quartz.CronTrigger as super class
查看发现spring3.0.5中org.springframework.scheduling.quartz.CronTriggerBean继承了org.quartz.CronTrigger(public class CronTriggerBeanextends CronTrigger),而在quartz2.1.3中org.quartz.CronTrigger是个接口(publicabstract interface CronTrigger extends Trigger),而在quartz1.8.5及1.8.4中org.quartz.CronTrigger是个类(public class CronTrigger extends Trigger),从而造成无法在applicationContext中配置触发器。这是spring3.1以下版本和quartz2版本不兼容的一个bug。(感谢tiren的回复,spring3.1以及以后版本支持quartz2)
其次,开始着手实现:
在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法仍然是普通类。很显然,第二种方式远比第一种方式来的灵活。本文主要使用第二种方法,第一种方法没有尝试。
我们就定义了一个类,在该类中我们有个execute方法,当Scheduler根据Trrigger设定的间隔时间触发这个类的时候执行的就是该类的execute方法。
java代码:
1 import org.springframework.context.support.ClassPathXmlApplicationContext; 2 /** 3 * @author sunyar 4 * 5 */ 6 7 public class QuartzJob { 8 /** 9 * 10 * @throws Exception 11 */ 12 private static int count = 0; 13 14 public void execute() throws Exception { 15 16 count++; 17 System.out.println("happy day" + count); 19 } 20 21 public static void main(String args[]) throws Exception { 22 new ClassPathXmlApplicationContext("file:src/main/webapp/WEB-INF/quartz-context.xml");//读取配置文件 23 } 24 }
quartz-context.xml
注:在此,为了方便阅读,本人将注释写成中文的,但是在写代码过程中,最好写成英文的,否则会报错。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
default-lazy-init="true">
<import resource="batch.service.applicationContext.xml"/>
<!--引入要定时执行的类-->
<bean id="quartzJob" class="com.**.it.***.batch.QuartzJob"></bean>
<!-- 开启定时任务-->
<bean id="quartzJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<!-- 定时执行的类 -->
<ref bean="quartzJob" />
</property>
<property name="targetMethod">
<!-- 定时执行的方法 -->
<value>execute</value>
</property>
</bean>
<bean id="quartzCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" >
<ref bean="quartzJobDetail" />
</property>
<!--每两秒钟触发执行一次 -->
<property name="cronExpression" >
<value>0/2 * * * * ? </value>
</property>
</bean>
<!-- 触发器工厂,将定时任务放到工厂中-->
<bean id="quartzJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- add trigger -->
<property name="triggers">
<list>
<!-- inject the timer task defined above-->
<ref local="quartzCronTrigger" />
</list>
</property>
</bean>
<!-- 结束 -->
</beans>
batch.service.applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:component-scan base-package="com.hp.it.mdm.batch" />
<!-- Add transactionManager by Bevan -->
<tx:annotation-driven transaction-manager="transactionManager" />
<tx:advice id="batchTxAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="find*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="get*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="search*" propagation="NOT_SUPPORTED" read-only="true" />
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="inactivate*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.hp.it.mdm.batch.services.*.*(..))" id="batchPointCut"/>
<aop:advisor advice-ref="batchTxAdvice" pointcut-ref="batchPointCut"/>
</aop:config>
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager">
</bean>
</beans>
注意:别忘了在web.xml中配置Spring
关于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 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 *
输出结果:
happy day1
happy day2
happy day3
happy day4
happy day5
happy day6
happy day7
happy day8
happy day9

浙公网安备 33010602011771号