Quartz是一個非常優秀的任務調度引擎,詳情請見官網:[url]http://www.quartz-scheduler.org/[/url]
而Spring很好地集成了Quartz,為企業級的任務調度提供了方便。
?
下面先看一個實現了Job接口的任務HelloWorldJob:
package com.springQuartz.example; import java.util.Map; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; public class HelloWorldJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { Map properties = context.getMergedJobDataMap(); System.out.println("Hello World!"); System.out.println("Previous Fire Time: "+context.getPreviousFireTime());//上次觸發任務的時間 System.out.println("Current Fire Time: "+context.getFireTime());//當然觸發時間 System.out.println("Next Fire Time: "+context.getNextFireTime());//下次觸發時間 System.out.println(properties.get("message")); System.out.println(); } }
這個Job輸出"HelloWorld",同時輸出上次、本次及下次觸發的時間。
?
我們看一下在applicationContext.xml中的配置:
<bean id="job" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.springQuartz.example.HelloWorldJob"/> <property name="jobDataAsMap"> <map> <entry key="triggerMessage" value="Job Message In JobDetail"/> <!--設置JobDetail中的值--> </map> </property> </bean> <bean id="trigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job"/> <!--觸發的job引用--> <property name="startDelay" value="1000"/> <!--設置延遲1秒后運行--> <property name="repeatInterval" value="10000"/> <!--設置每10秒觸發一次--> <property name="jobDataAsMap"> <map> <entry key="triggerMessage" value="Job Message From Trigger"/> <!--設置Trigger中的值--> </map> </property> </bean> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="trigger"/> </list> </property> </bean>
我們將HelloWorldJob實現成JobDetailBean類,并配置觸發器simpleTriggerBean
?
最后我們的測試類:
package com.springQuartz.test; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String args[]){ BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
運行結果如下:
2011-01-16 20:48:18,437 INFO - Starting Quartz Scheduler now Hello World! Previous Fire Time: null Current Fire Time: Sun Jan 16 20:48:19 CST 2011 Next Fire Time: Sun Jan 16 20:48:29 CST 2011 Job Message From Trigger Hello World! Previous Fire Time: Sun Jan 16 20:48:19 CST 2011 Current Fire Time: Sun Jan 16 20:48:29 CST 2011 Next Fire Time: Sun Jan 16 20:48:39 CST 2011 Job Message From Trigger
下面說明幾點:
1)首次觸發是輸出的Previous Fire Time為null
2)jobDataAsMap的說明:在HelloWorldJob.java中getMergedJobDataMap是JobDetail和Trigger上的JobDataMap的合并,兩者數據如果沖突,則Trigger上的數據將覆蓋JobDetail中的。運行結果也證明了,我們在Job中設置的值沒有輸出,而輸出了"Job Message From Trigger"。
3)我們看到HelloWorldJob實現了Job接口,代碼上依賴了Quartz的接口
?
下面我們討論另外一種更普遍的,去除接口依賴的實現
?
主要的applicationContext.xml文件的配置
<bean id="jobService" class="com.springQuartz.service.JobServiceImpl"> </bean> <bean id="invokeJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="jobService" /> <!--目標Job--> </property> <property name="targetMethod"> <value>JobServiceImpl中的特定方法</value> <!--目標方法--> </property> <property name="concurrent"> <value>false</value> <!--設置是否同步--> </property> </bean> <bean id="jobServiceCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="invokeJob" /> <property name="cronExpression" value="5/10 * * * * ?" /> </bean> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref local="jobServiceCronTrigger"/> </list> </property> </bean>?
1)首先我們配置具體的Job信息--JobServiceImpl,這個類可以不實現Quartz中的Job接口
2)最主要的MethodInvokingJobDetailFactoryBean,可以使得1)可行
3)相對于上面的例子,我們使用CronTriggerBean實現trigger,實現更靈活的時間配置
4)默認情況下,Quartz Jobs是無狀態的,可能導致jobs之間互相的影響。如果你為相同的
JobDetail
指定兩個Trigger, 很可能當第一個job完成之前,第二個job就開始了。如果
JobDetail
對象實現了
Stateful
接口,就不會發生這樣的事情。 第二個job將不會在第一個job完成之前開始。為了使得jobs不并發運行,設置
MethodInvokingJobDetailFactoryBean
中的
concurrent
標記為
false
。
?
?
最近學習的東西記錄下來,歡迎大家拍磚
?
?
?
?
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
