1. 程式人生 > >Quartz 框架 教程(中文版)2.2.x 之第六課 CronTrigger

Quartz 框架 教程(中文版)2.2.x 之第六課 CronTrigger

第六課 CronTrigger

         CronTriggerSimpleTrigger更常用,當你需要一個基於日曆般概念的作業排程器,而不是像SimpleTrigger那樣精確指定間隔時間。

使用SimpleTrigger,你可以這樣指定觸發時間表例如“每週五的中午”,或是“每週末的上午9:30”,甚至是“一月份每週一、三、五上午9:0010:00之間每5分鐘”。

雖然如此,跟SimpleTrigger一樣,CronTrigger也需要指定startTime讓排程器生效,指定endTime讓排程器終止。

Cron表示式

       Cron表示式用於配置CronTrigger例項。Cron

表示式實際上是由7個子表示式組成的字串,描述了時間表的詳細資訊。這些子表示式用空格隔開,分別代表:

1、秒

2、分

3、小時

4、月份中的天數

5、月

6、星期中的天數

7、年(可選)

       一個完整的Cron表示式的字串例子“0 0 12 ? * WED”,意思是“每週三的上午12:00:00”。

       每個了表示式都包含“和”、“或”的兩種排列,例如,上一個例子中星期中的天數字段(顯示的是“WED”)可以替換為“MONFRI”,“MON,WED,FRI”,甚至是“MON-WED,SAT”。

萬用字元(“*”)可用來表示該欄位的任意值,因此“*”在上面的例子中的月份欄位表示“每個月”,“*

”在星期中的天數字段由此明顯是表示“一週的任何一天”。

       所有的欄位都定義了一套可用的值。這些值應該非常明顯易懂——例如秒和分的值是從059,小時的值是從023.月份中的天數是從031,但是你需要特別注意這個月實際上有多少天!月份的值指定在011之間,或者可以使用字串JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC。星期中的天數的值指定在17之間(1表示星期天),或是使用字串SUNMONTUEWEDTHUFRISAT

       “/”字元可用來表示增量的值。例如,如果你在分鐘欄位寫“0/15”,這表示“每次從一小時中的第0分鐘開始,每隔15

分鐘觸發”,如果你在分鐘欄位上寫“3/20”,這表示“每次從一小時中的第3分鐘開始,每隔20分鐘觸發”——換句話說,這跟在分鐘欄位上指定“32343”是一樣的。注意細微的區別:“/35”不是表示“每隔35分鐘”,而是表示“每次從一小時中的第0分鐘開始,每隔35分鐘觸發”,相當於指定“035”。

       “?”字元允許出現在月份中的天數和星期中的天數字段中。它一般用來指定“不關心的值”。當你需要在這兩個欄位中的一個指定不確定的值是非常方便的,這個字元不能用在其他的欄位中。可以檢視下面的例子(或是CronTriggerJavaDoc文件)獲得更詳細的說明。

       “L”字元允許出現在月份中的天數和星期中的天數字段中。這個字元是“last”的縮寫,但是在這兩個欄位中有不同的含義。例如,“L”字元出現在月份中的天數字段中表示“每月的最後一天”——131日,平年的228日。如果該字元單獨用在星期中的天數字段時,僅僅是表示“7”或是“SAT”。但是在星期中的天數字段中該字元用在其他值的後面,表示“每月的最後一個星期幾”——例如“6L”或是“FRIL”都表示“每月的最後一個星期五”。你也可以指定每月最後一天的偏移數,例如“L3”表示日曆月份的最後三天。當你使用“L”字元時,最好不要使用排列值或是帶範圍的值,否則你會對結果感到意外和難以理解。

      “w”字元用來指定給定日期的最近一個工作日(工作日指的是從週一到週五)。例如,如果你在月份中的天數字段的值指定為“15w”,這表示“離每月15號最近的工作日”。

      “#”字元用來指定每月的第N個工作日,例如,星期中的天數字段的值為“6#3”或是“FRI#3”表示“每月的第三個星期五”。

       下面演示了一些表示式的例子和含義——你可以在org.quartz.CronExpressionJavaDoc找到更多資訊。

Cron表示式案例

        Cron案例1——僅僅表示每隔5分鐘觸發一次:

"00/5 * * * ?"

        Cron案例2——表示每隔5分鐘,在過了10秒後觸發一次(例如上午10:00:1010:05:10等):

"100/5 * * * ?"

        Cron案例3——表示每個週三到週五,在上午10:3011:3012:3013:30分觸發:

"030 10-13 ? * WED,FRI"

       Cron案例4——表示每月從5號到20號,上午8時到10時之間的每半小時觸發,注意這個觸發器只在8:008:309:009:30分觸發,上午10:00不會觸發:

"00/30 8-9 5,20 * ?"

      注意有些排程需求因太複雜例如“上午9:0010:00之間的每5分鐘,下午1:0010:00的每20分鐘”,而不能用單一的觸發器來表示。這種情況的解決方案是建立兩個簡單的觸發器,將它們註冊到排程器中去運行同一個作業任務。

構建CronTriggers

       CronTrigger例項物件可以使用TriggerBuilder(針對    觸發器主要的引數)和CronScheduleBuilder(針對CronTrigger的指定引數)來建立。為了使用這些建立類時滿足DSL格式,使用靜態匯入:

import static org.quartz.TriggerBuilder.*;
import static org.quartz.CronScheduleBuilder.*;
import static org.quartz.DateBuilder.*:

       建立一個觸發器,每天從上午8點到下午5點,每隔2分鐘觸發一次:

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
    .forJob("myJob", "group1")
    .build();

       建立一個觸發器,每天的上午10:42分觸發一次:

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(dailyAtHourAndMinute(10, 42))
    .forJob(myJobKey)
    .build();

      或者

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 42 10 * * ?"))
    .forJob(myJobKey)
    .build();

CronTrigger觸發失敗指令

         CronTrigger有幾條指令,用來告知Quartz當觸發失敗時該如何操作。(在第四課更多關於觸發器已經介紹過觸發失敗的情況)。這些指令在CronTrigger類中設計成常量(包含JavaDoc描述了它們的行為)。指令有:

       CronTrigger的觸發失敗指令常量:

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW

        所有的觸發器都可以使用Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令,並且這條指令也是所有觸發器的預設指令。

       “智慧策略”指令可以從CronTriggerMISFIRE_INSTRUCTION_FIRE_NOW當中獲得解釋。JavaDoc文件中CronTriggerupdateAfterMisfire方法解釋了動態選擇行為的更詳細的資訊。

    當你建立CronTrigger時,可以通過CronSchedulerBuilder指令觸發失敗指令作為排程器的一部分。

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?")
        ..withMisfireHandlingInstructionFireAndProceed())
    .forJob("myJob", "group1")
    .build();