1. 程式人生 > >Quartz教程 第6課 CronTrigger

Quartz教程 第6課 CronTrigger

6課 CronTrigger

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

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

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

6.1Cron表示式

Cron表示式用於配置CronTrigger例項。Cron表示式實際上是由7個子表示式組成的字串,描述了

schedule的詳細資訊。這些子表示式用空格隔開,分別代表:

  1. 月份中的天數
  2. 星期中的天數
  3. (可選欄位)

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

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

萬用字元(*)可用來表示該欄位的任意值,因此*在上面的例子中的月份欄位表示每個月*在星期中的天數字段由此明顯是表示一週的任何一天

所有這些欄位都可以設定一些合法的值。這些值可以是非常明確的,例如對於秒和分來說

0-59的數字,對於小時來說0-23的數字。月份中的天數可以是131的任意值,但是你需要小心那個月總共有多少天!月份可以指定的值為011,或者使用字串JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOVDEC。星期中的天可以指定的值為1到7(1=Sunday),或者使用字串SUN, MON, TUE, WED, THU, FRISAT

/字元可用來表示增量的值。例如,如果你在分鐘欄位寫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表示每月的第三個星期五

下面演示了一些Cron表示式的例子和它們的含義你可以在org.quartz.CronExpression或者JavaDoc找到更多資訊。

6.2Cron表示式示例

CronTrigger示例1 -建立一個trigger的表示式,每5分鐘觸發一次:

0 0/5 * * * ?

CronTrigger示例2 -建立一個trigger的表示式,每5分鐘觸發一次,在每分鐘的10秒之後(10:00:10 am, 10:05:10 am等等)

10 0/5 * * * ?

CronTrigger示例3 -建立一個trigger的表示式,每週三和週五的10:3011:3012:3013:30觸發:

0 30 10-13 ? * WED,FRI

CronTrigger示例4 -建立一個trigger的表示式,在每一個月的第5天和第20天的上午8點到上午10點之間的每半小時觸發一次。注意,在上午10:00不會觸發,只會在8:008:309:009:30觸發:

0 0/30 8-9 5,20 * ?

注意,有一些排程需求用單個trigger表達太複雜:例如“上午9:00到上午10:00之間的每5分鐘,下午1:00到下午10:00的每20分鐘”。這個場景的解決方案是簡單的場景兩個trigger,將它們註冊到相同的job裡。

6.3 構建CronTrigger

CronTrigger例項是由TriggerBuilder(用於設定trigger的主要屬性)CronScheduleBuilder(用於設定CronTrigger特定的屬性)構建的。以DSL風格使用這些構建器,可使用靜態匯入:

importstaticorg.quartz.TriggerBuilder.*;

import staticorg.quartz.CronScheduleBuilder.*;

import staticorg.quartz.DateBuilder.*:

1、構建一個trigger,每天的從上午8點到下午5點,每兩分鐘觸發一次:

  trigger = newTrigger()

    .withIdentity("trigger3","group1")

    .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))

    .forJob("myJob","group1")

    .build();

2、構建一個trigger,每天上午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();

3、構建一個trigger,在週三上午10:42(指定時區TimeZone,而不是系統預設時區)觸發:

  trigger = newTrigger()

    .withIdentity("trigger3", "group1")

    .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42))

    .forJob(myJobKey)

    .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))

    .build();

或者

  trigger = newTrigger()

    .withIdentity("trigger3","group1")

    .withSchedule(cronSchedule("0 42 10 ? * WED"))

    .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles"))

    .forJob(myJobKey)

    .build();

6.4CronTrigger失敗指令

下面幾條指令用來告知QuartzCronTrigger觸發失敗時,它應該怎麼做。(在本教程的第4Trigger詳解已經介紹過失敗機制)CronTrigger自己將指令定義成了常量(包含描述它們行為的JavaDoc)。這些指令包括:

CronTrigger失敗指令常量