一、背景
上次我們介紹瞭如何使用Spring Task進行完成定時任務的編寫,這次我們使用Spring整合Quartz的方式來再一次實現定時任務的開發,以下奉上開發步驟及注意事項等。
二、開發環境及必須jar包依賴
1.開發環境
- Spring 4.2.6.RELEASE
- Maven 3.3.9
- JDK 1.7
- Idea 15.04
2.必不可少jar包依賴
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-context-support</artifactId> 4 <version>4.2.6.RELEASE</version> 5 </dependency> 6 <dependency> 7 <groupId>org.quartz-scheduler</groupId> 8 <artifactId>quartz</artifactId> 9 <version>2.2.1</version> 10 </dependency>
三、開發步驟
【1】.基於特定基類
1. 編寫任務類,該類需要繼承自QuartzJobBean
1 package com.hafiz.www.cron; 2 3 import org.quartz.JobExecutionContext; 4 import org.quartz.JobExecutionException; 5 import org.slf4j.Logger; 6 import org.slf4j.LoggerFactory; 7 import org.springframework.scheduling.quartz.QuartzJobBean; 8 9 /** 10 * Desc:第二個基於Spring Quartz的定時任務 11 * Created by hafiz.zhang on 2016/12/11. 12 */ 13 public class SecondCron extends QuartzJobBean { 14 private static final Logger logger = LoggerFactory.getLogger(SecondCron.class); 15 private Integer timeout; 16 17 //排程工廠例項化後,經過timeout時間開始執行排程 18 public void setTimeout(Integer timeout) { 19 this.timeout = timeout; 20 } 21 22 @Override 23 protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { 24 logger.info("定時任務2進行中......."); 25 // do something else 26 } 27 }
2.在spring配置檔案中配置作業類JobDetailFactoryBean、作業排程的觸發方式(觸發器)、排程工廠
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:task="http://www.springframework.org/schema/task" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 6 http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> 7 8 <bean name="secondCron" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> 9 <property name="jobClass" value="com.hafiz.www.cron.SecondCron"/> 10 <property name="jobDataAsMap"> 11 <map> 12 <entry key="timeout" value="0"/> 13 </map> 14 </property> 15 </bean> 16 17 <!--按照一定頻率的觸發器--> 18 <!--<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> 19 <property name="jobDetail" ref="secondCron"/> 20 <property name="startDelay" value="0"/> 21 <property name="repeatInterval" value="2000"/> 22 </bean>--> 23 24 <!--Cron表示式觸發器--> 25 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 26 <property name="jobDetail" ref="secondCron"/> 27 <property name="cronExpression" value="0/5 * * * * ?"/> 28 </bean> 29 30 <!--配置排程工廠--> 31 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 32 <property name="triggers"> 33 <list> 34 <!--<ref bean="simpleTrigger"/>--> 35 <ref bean="cronTrigger"/> 36 </list> 37 </property> 38 </bean> 39 </beans>
注意:
1).org.springframework.scheduling.quartz.JobDetailBean有兩個屬性.
jobClass屬性即我們在java程式碼中定義的任務類.
jobDataAsMap屬性即該任務類中需要注入的屬性值.
2).Quartz的作業觸發器有兩種(兩種任選其一就行)
org.springframework.scheduling.quartz.SimpleTriggerFactoryBean:只支援按照一定頻度呼叫任務,如每隔30分鐘執行一次.
org.springframework.scheduling.quartz.CronTriggerFactoryBean:支援到指定時間執行一次,如每天12:00執行一次等.
關於第二種觸發器的Cron表示式,請參見另一篇部落格:擺脫Spring 定時任務的@Scheduled cron表示式的困擾
3).org.springframework.scheduling.quartz.SchedulerFactoryBean的引數triggers指定的就是之前配置的觸發器的名字.
3.執行結果
【2】.不基於特定的基類
1.編寫任務排程類
package com.hafiz.www.cron; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Desc:基於Spring整合Quartz進行完成定時任務 * Created by hafiz.zhang on 2016/12/11. */ public class ThirdCron { private static final Logger logger = LoggerFactory.getLogger(ThirdCron.class); public void executeJob() { logger.info("定時任務3進行中......."); // do something else } }
2.在spring配置檔案中配置作業類MethodInvokingJobDetailFactoryBean、作業排程的觸發方式(觸發器)、排程工廠
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.springframework.org/schema/beans 4 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> 5 6 <bean name="thirdCron" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 7 <property name="targetObject"> 8 <bean class="com.hafiz.www.cron.ThirdCron"/> 9 </property> 10 <property name="targetMethod" value="executeJob"/> 11 <!--作業不併發排程--> 12 <property name="concurrent" value="false"/> 13 </bean> 14 15 <!--按照一定頻率的觸發器--> 16 <!--<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> 17 <property name="jobDetail" ref="thirdCron"/> 18 <property name="startDelay" value="0"/> 19 <property name="repeatInterval" value="2000"/> 20 </bean>--> 21 22 <!--Cron表示式觸發器--> 23 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> 24 <property name="jobDetail" ref="thirdCron"/> 25 <property name="cronExpression" value="0/5 * * * * ?"/> 26 </bean> 27 28 <!--配置排程工廠--> 29 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 30 <property name="triggers"> 31 <list> 32 <!--<ref bean="simpleTrigger"/>--> 33 <ref bean="cronTrigger"/> 34 </list> 35 </property> 36 </bean> 37 </beans>
注意:MethodInvokingJobDetailFactoryBean,有兩個關鍵屬性:
targetObject指定任務類.
targetMethod指定執行的方法.
3.執行結果
四、總結
Quartz屬於重量級的定時任務框架,我們一般都會選擇輕量級的如Spring Task定時任務進行開發,但是遇到比較棘手的,這也是一種解決問題的方式。