1. 程式人生 > >Spring定時任務的實現:Quartz

Spring定時任務的實現:Quartz

Java任務排程分類

  • 從實現的技術上來分類,目前主要有三種技術:

  1. Java自帶的java.util.Timer類,這個類允許你排程一個java.util.TimerTask任務。使用這種方式可以讓你的程式按照某一個頻度執行,但不能在指定時間執行。一般用的較少,這篇文章將不做詳細介紹。
  2. 使用Quartz,這是一個功能比較強大的的排程器,可以讓你的程式在指定時間執行,也可以按照某一個頻度執行,配置起來稍顯複雜,稍後會詳細介紹。
  3. Spring3.0以後自帶的task,可以將它看成一個輕量級的Quartz,而且使用起來比Quartz簡單許多。
  • 從作業類的繼承方式來講,可以分為兩類:

  1. 作業類需要繼承自特定的作業類基類,如Quartz中需要繼承自org.springframework.scheduling.quartz.QuartzJobBean;java.util.Timer中需要繼承自java.util.TimerTask。
  2. 作業類即普通的java類,不需要繼承自任何基類。

      注:個人推薦使用第二種方式,因為這樣所以的類都是普通類,不需要事先區別對待。

  • 從任務排程的觸發時機來分,有以下兩種:

  1. 每隔指定時間則觸發一次,在Quartz中對應的觸發器為:org.springframework.scheduling.quartz.SimpleTriggerBean
  2. 每到指定時間則觸發一次,在Quartz中對應的排程器為:org.springframework.scheduling.quartz.CronTriggerBean

注:並非每種任務都可以使用這兩種觸發器,如java.util.TimerTask任務就只能使用第一種。Quartz和spring task都可以支援這兩種觸發條件。

 

對於spring的整合其中的任務,spring提供了幾個類、介面(這些類都實現了Job介面):

  org.springframework.scheduling.quartz.QuartzJobBean

  org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean.MethodInvokingJob 

  org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean.StatefulMethodInvokingJob

  

  QuartzJobBean和MethodInvokingJob是無狀態的,StatefulMethodInvokingJob是有狀態的。

 

 

1、Scheduler的配置

    說明:Scheduler包含一個Trigger列表,每個Trigger表示一個作業。

 

2、Trigger的配置

<bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">  
       <property name="jobDetail" ref="testJobDetail"/>  
       <property name="cronExpression" value="*/1 * * * * ?"/><!-- 每隔1秒鐘觸發一次 -->  
</bean>  

    說明:

         1)Cron表示式的格式:秒 分 時 日 月 周 年(可選)。

               欄位名                 允許的值                        允許的特殊字元  

               秒                         0-59                               , - * /  

               分                         0-59                               , - * /  

               小時                   0-23                               , - * /  

               日                         1-31                               , - * ? / L W C  

               月                         1-12 or JAN-DEC          , - * /  

               周幾                     1-7 or SUN-SAT            , - * ? / L C #  

               年 (可選欄位)     empty, 1970-2099      , - * /

               “?”字元:表示不確定的值

               “,”字元:指定數個值

               “-”字元:指定一個值的範圍

               “/”字元:指定一個值的增加幅度。n/m表示從n開始,每次增加m

               “L”字元:用在日表示一個月中的最後一天,用在周表示該月最後一個星期X

               “W”字元:指定離給定日期最近的工作日(週一到週五)

               “#”字元:表示該月第幾個周X。6#3表示該月第3個週五

         2)Cron表示式範例:

                 每隔5秒執行一次:*/5 * * * * ?

                 每隔1分鐘執行一次:0 */1 * * * ?

                 每天23點執行一次:0 0 23 * * ?

                 每天凌晨1點執行一次:0 0 1 * * ?

                 每月1號凌晨1點執行一次:0 0 1 1 * ?

                 每月最後一天23點執行一次:0 0 23 L * ?

                 每週星期天凌晨1點實行一次:0 0 1 ? * L

                 在26分、29分、33分執行一次:0 26,29,33 * * * ?

                 每天的0點、13點、18點、21點都執行一次:0 0 0,13,18,21 * * ?

3、JobDetail的配置

<bean id="testJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">   
        <property name="targetObject" ref="testJob"/>  
        <property name="targetMethod" value="execute"/>  
        <property name="concurrent" value="false"/>
        <!-- 是否允許任務併發執行。當值為false時,表示必須等到前一個執行緒處理完畢後才再啟一個新的執行緒 -->  
</bean>  

4、業務類的配置

<bean id="testJob" class="com.cjm.web.service.quartz.TestJob"/>  

5、業務類原始碼

public class TestJob {  
    public void execute(){  
        try{  
              //.......
         }catch(Exception ex){  
             ex.printStackTrace();  
         }  
     }  
}  

    說明:業務類不需要繼承任何父類,也不需要實現任何介面,只是一個普通的java類。

 

在Spring配置和Quartz整合內容時,有兩點需要注意

 1、在<Beans>中不能夠設定default-lazy-init="true",否則定時任務不觸發,如果不明確指明default-lazy-init的值,預設是false。

2、在<Beans>中不能夠設定default-autowire="byName"的屬性,否則後臺會報org.springframework.beans.factory.BeanCreationException錯誤,這樣就不能通過Bean名稱自動注入,必須通過明確引用注入