1. 程式人生 > >定時任務Quartz Scheduler概念詳解

定時任務Quartz Scheduler概念詳解

首先認識明確幾個關於Quartz Scheduler的概念。
 
排程器:負責對使用者定義的所有任務進行排程的類。
 
觸發器:觸發器在邏輯上包含兩個屬性,即如何觸發該排程器和觸發該排程器之後進行怎麼樣的操作,在Quartz Scheduler中觸發器的觸發事件為特定時間。時間可以為一個時間段,也可以為時間點。
 
任務(jobDetail):觸發器在被觸發後進行的操作,可以指定任意一個類的某個方法。觸發器被觸發之後將呼叫該類的指定方法。
 
 
 
在spring.jar包中包含了對Quartz Scheduler進行操作的類:
 
1.       org.springframework.scheduling.quartz.SchedulerFactoryBean
 
該類負責在spring容器中建立排程器。其最重要的屬性有triggers,這是一個List定義了該排程器負責排程的所有觸發器。還有一個屬性為autoStartup,該類指定是否在spring構造該類完成之後開始執行排程。一般設定為true。
 
2.       org.springframework.scheduling.quartz.CronTriggerBean
 
該類負責在spring容器中建立一個觸發器,該類的ID應該在某個SchedulerFactoryBean屬性的List中被引用,這樣這個觸發器才能保證被某個指定排程器排程。在該類中應該指定兩個屬性,觸發規則(cronExpression)和觸發要執行任務(jobDetail)。觸發規則(cronExpression)是一個指定規則的字串,指定了在什麼時候觸發該觸發器。在下文中介紹,jobDetail屬性配置為一個MethodInvokingJobDetailFactoryBean,由MethodInvokingJobDetailFactoryBean負責生成任務類。
 
3.       org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
 
該類負責生成具體的任務,其實任務非常簡單,只需要指定某個物件的某個方法即可,在觸發器觸發時,即呼叫指定物件的指定方法。
 
 
 
程式碼示例
 

spring配置檔案

<?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:tx="http://www.springframework.org/schema/tx"
 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
 
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
 
    <!-- 任務排程器生成器,Spring生成具有指定屬性排程器物件 -->
 
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
 
       <!-- 生成的排程器所管理的所有觸發器 -->
 
       <property name="triggers">
 
           <list>
 
              <ref bean="testTrigger" />
 
           </list>
 
       </property>
 
       <property name="autoStartup" value="true" />
 
    </bean>
    <!-- 觸發器生成器類,用被指定的排程器排程生成指定規則的觸發器物件 -->
 
    <bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
 
       <!-- 觸發後要做的操作,這個操作由spring管理,只需要指定一個MethodInvokingJobDetailFactoryBean -->
 
       <property name="jobDetail" ref="testJobDetail" />
 
       <!-- 觸發規則,這裡的觸發規則是每隔2秒鐘後觸發一次 -->
 
       <property name="cronExpression" value="*/2 * * * * ?" /><!--  -->
 
    </bean>
 
    <!--任務生成器,由spring管理,只需要指定其對應的物件和方法即可,任務的執行即是某個物件呼叫一個方法 -->
 
    <bean id="testJobDetail"
 
        class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
 
       <!-- 指定該任務對應的呼叫物件,這個物件所屬的類無需實現任何介面-->
 
        <property name="targetObject" ref="testJob" />
 
       <!-- 指定在targetObject物件中某個的方法 -->
 
       <property name="targetMethod" value="execute" />
 
       <!-- 是否允許任務併發執行。當值為false時,表示必須等到前一個執行緒處理完畢後才再啟一個新的執行緒 -->
 
       <property name="concurrent" value="false" />
 
    </bean>
 
    <!-- 一個普通的類,用於測試 -->
 
    <bean id="testJob" class="com.javacat.spring.TestJob"/>
 
</beans>

用於測試的類:

package com.javacat.spring;
 
import java.util.Date;
 
public class TestJob {
 
    private static int count = 0;
 
    public void execute() {
 
       try {
 
           Thread.sleep(3000);
 
           System.out.println(new Date() + "--任務I第"+ ++count +"次被觸發");
 
       } catch (Exception ex) {
 
           ex.printStackTrace();
 
       }
 
    }
 
} 



下面介紹如何在spring中定義觸發器的生成規則:
 
 生成規則cronExpression屬性是一個空格隔開的字串,每個部分分別標識指定的時間的秒,分,時,日,月,周幾,年屬性。先看一個表格
 
 
欄位名
 
允許的值
 
允許的特殊字元
 
 

 
0-59
 
- * /
 
 

 
0-59
 
- * /
 
 

 
0-23
 
- * /
 
 

 
1-31
 
- * / L W C ?
 
 

 
1-12 or JAN-DEC
 
- * /
 
 
周幾
 
1-7(1對應星期天)or SUN-SAT
 
- * ? / L C #
 
 
年(可選欄位)
 
1970-2099 empty
 
- * /

字元釋義
 
“?”字元:表示不確定的值
 
“,”字元:指定數個值
 
“-”字元:指定一個值的範圍
 
“/”字元:指定一個值的增加幅度。n/m表示從n開始,每次增加m
 
“L”字元:用在日表示一個月中的最後一天,用在周表示該月最後一個星期X
 
“W”字元:指定離給定日期最近的工作日(週一到週五)
 
“#”字元:表示該月第幾個周X。6#3表示該月第3個週五
 
 
 
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 * * ?