使用Spring整合Quartz輕鬆完成定時任務

阿豪聊乾貨發表於2016-12-11

 一、背景

  上次我們介紹瞭如何使用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定時任務進行開發,但是遇到比較棘手的,這也是一種解決問題的方式。

相關文章