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

 

posted @ 2015-08-13 16:26  Yara  阅读(150)  评论(1)    收藏  举报