Quartz2.2.x官方文檔2.2.X—第三章 6.CronTrigger


Table of Contents | ‹ Lesson 5 | Lesson 7 ›

課程 6: CronTrigger

CronTrigger比SimpleTrigger更經常被使用,如果你需要任務觸發調度基於日曆週期來循環觸發,而不是簡單的的指定SimpleTrigger的觸發時間。

關於CronTrigger, 你可以指定觸發調度,例如"每週五的中午"或者"每個工作日的9:30am",甚至是"一月份的每個星期一、星期三、星期五的9:00am至10:00am每五分鐘執行一次"。

即使如此, 像SImpleTirgger一樣,CronTrigger也有一個 startTime 指定調度開始的時間, (可選) endTime 則指定調度什麼時間會被關閉。

Cron 表達式

Cron-表達式 用於配置CronTrigger實例。Cron-表達式字符串實際上是由7個子表達式組成的,它描述了調度計劃的詳細細節。這些子表達式之間用空格分割,並表示爲:

  1. 月的天
  2. 月份
  3. 星期幾
  4. 年 (可選字段)

一個完整的Cron表達式例子例如"0 0 12 ? * WED"-含義是"每星期三12:00:00 pm"執行。

單個子表達式可以包含範圍或者列表。例如,星期的天數字段在之間的例子中可以替換爲"MON-FRI","MON,WD,FRI",甚至是"MON-WED,SAT"。

通配符可以用來表示"每一個這個字段可能使用的值。因此,前一個示例的"月份"字段表示的含義是"每一個月"。因此在周的日字段上'*'的含義代表着"這一週的每一天"。

所有字段都有一組可以設置的有效值。這些值有那些是顯而易見的 - 例如秒和分鐘是數字0到59,小時的值是0到23。月的日的值是1-31,但是你需要注意一個月裏有多少天!月份可以指定的值是0到11,或者使用字符串JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC。星期的天可以指定的值是從1到7,或者使用字符串SUN, MON, TUE, WED, THU, FRI 和 SAT。

‘/’字符可以被用來指定增長值。例如,如果你在分鐘字段設置'0/15',它的含義是'在該小時0分鐘開始,並且每15分鐘執行一次’。 如果你在分鐘字段使用‘3/20’,它的含義是‘在該小時3分鐘開始,並每20分鐘執行一次’ - 或者另一種含義是在分鐘字段指定'3,23,43',注意"/35"的含義不是"每35分鐘" - 它的含義是"在該小時0分鐘開始,每35分鐘執行一次" - 或者另一個種解釋是指定"0,35"。

‘?’字符可以用在day-of-month和day-of-week字段上. 它被使用來指定"無指定值"。當你需要再這兩個字段之間選擇一個字段指定,而不是另一個時,這是十分有用的。看下面的例子說明(CronTrigger JavaDoc)。

‘L’字符可以被用在day-of-month和day-of-week字段. 這個字符是"last"的縮寫,但是在這兩個字段上有不同的含義。例如,在day-of-month字段上"L"表示含義"月的最後一天"- 一月31天,平年2月28天。如果在day-of-week字段使用,它僅表示"7"或者"SAT"。但是在day-of-week字段使用其他值,它的含義是"月的最後第XXX天"。你也可以指定月的最後一天的偏移量,例如"L-3"含義是日曆月的倒數第三天。當使用'L'選項,不能使用指定列表,或者範圍值,你將會獲得混亂的結果。

‘W’用來指定離給定日期最近的工作日(週一至週五)。例如, 如果在day-of-month字段指定"15W"值,它的含義是"離本月15最近的工作日"。

‘#’是用來指定本月的第XXX個工作日。 例如,在day-of-week字段使用"6#3"或者"FRI#3"含義是"本月的第三個星期五"。

關於更多表達式的例子和他們的含義-你可以通過JavaDoc關於org.quartz.CronExpression來查閱。

Cron表達式例子

CronTrigger 例子 1 - 創建一個每5分鐘觸發一次的Cron表達式

“0 0/5 * * * ?”

CronTrigger 例子 2 - 創建一個每5分鐘在10秒觸發的Corn表達式

“10 0/5 * * * ?”

CronTrigger 例子 3 - 創建一個在星期三、星期五10:30,11:30,12:30和13:30觸發的Cron表達式。

“0 30 10-13 ? * WED,FRI”

CronTrigger 例子 4 - 創建一個每月第5天、第20天的8點和9點,每半小時觸發一次的Cron表達式。注意觸發器不會再10:00am觸發,只在8:00,8:30,9:00和9:30觸發。

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

主要有些表達式太過複雜,無法用一個觸發器表達-例如"在9:00和10:00之間每5分鐘觸發一次,在1:00pm到10:00pm之間每20分鐘觸發一次"。在這個解決方案中是簡單的創建兩個觸發器,把它們註冊到同一個任務中。

Building CronTriggers

CronTrigger實例使用TriggerBuilder構建(trigger的主要屬性) 和 CronScheduleBuilder (關於Cron觸發器特定的屬性). 在DSL-風格使用這些構建,使用靜態導入:


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

構造一個觸發器在8am到5pm之間每隔一分鐘觸發一次:


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

構建一個觸發器,在10:42 am觸發:


  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();

構造一個觸發器,在系統默認時區之外的星期三10:42 am觸發:


  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();

CronTrigger 失敗介紹

當一個關於CronTrigger的異常發生下面的說明可以通知Qaurtz它可以做什麼。(關於本教程中觸發器導致錯誤的情況). 這些指令被定義爲CronTrigger本身的常量(包含描述它們行爲的JavaDoc). 這些說明包含:

CronTrigger的錯誤命令常量


MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW

所有觸發器都有Trigger.MISFIRE_INSTRUCTION_SMART_POLICY命令可以被使用,這個命令也是所有觸發器類型的默認選項。"智能策略"被CronTrigger觸發器解釋爲MISFIRE_INSTRUCTION_FIRE_NOW. CronTrigger.updateAfterMisfire()方法的JavaDoc解釋了它的具體行爲。

當構建CronTriggers時,你可以指定錯誤指令作爲構建調度的一部分(例如 CronSchedulerBuilder):


  trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?")
        ..withMisfireHandlingInstructionFireAndProceed())
    .forJob("myJob", "group1")
    .build();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章