Quartz教程六--CronTrigger

目錄
0. Quartz教程–快速入門
1. Quartz教程一–使用Quartz
2. Quartz教程二–API、Job與Trigger
3. Quartz教程三–Job與JobDetail介紹
4. Quartz教程四–Trigger介紹
5. Quartz教程五–SimpleTrigger
6. Quartz教程六–CronTrigger
7. Quartz教程七–TriggerListener和JobListener
8. Quartz教程八–SchedulerListener

如果你需要的是基於日曆表示法的調度,而不是基於指定間隔的簡單調度,那麼CronTrigger比SimpleTrigger更合適。

使用CronTrigger,你可以配置這樣的調度:“每週五的中午”,或者“每個工作日的上午9:30”,或者“在一月的每個週一、週三和週五的上午9點到10點之間每隔5分鐘”。

與SimpleTrigger一樣,CronTrigger需要設置startTime屬性,表示調度生效的時間,以及(可選的)endTime屬性,表示調度的結束時間。

Cron表達式

Cron表達式用於配置CronTrigger的實例,它由7個字段組成,字段之間由空格分開,它們表示的含義如下:

1. 秒 (Seconds)
2. 分鐘 (Minutes)
3. 小時 (Hours)
4. 日(一個月的一天) (Day-of-Month)
5. 月份   (Month)
6. 周(一週的一天) (Day-of-Week)
7. 年份(可選的) (Year)

一個完整的Cron表達式的例子如字符串:”0 0 12 ? * WED” - 表示“每週三的中午12:00:00”;

每一個字段可以包含範圍或者列舉。比如,上例中的字段(即”WED“)可以被替換爲:”MON-FRI”, “MON,WED,FRI”, 或者”MON-WED,SAT”。

通配符()表示該字段上每一個可取的值。因此,上例中字段上的表示“每個月”。字段上的*表示“一週的每一天”。

所有的字段都有一些可取的值的集合。有些就很明顯 - 比如,分鐘字段可以取0到59的整數,小時字段可以取0到23的整數,字段(Day-of-Month)可以取1到31的整數,不過你需要注意指定的月份到底有多少天。字段可以取0到11之間的整數,或者使用字符串表示:JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 和 DEC。字段(Days-of-Week)可以取的值爲1到7(1表示Sunday),或者使用字符串表示:SUN, MON, TUE, WED, THU, FRI and SAT。

字符‘/’表示增量。比如,分鐘字段使用”0/15“,表示”在這個小時內,從0分鐘開始,每隔15分鐘“;如果分鐘字段使用”3/20“,則表示”在這個小時內,從第3分鐘開始,每隔20分鐘“,這與在分鐘字段使用“3,23,43”表示的含義是一樣的。注意一個細節,“/35”的含義並不是“每隔35分鐘”,而是“在這個小時內,從第0分鐘開始,每隔35分鐘”。

字符’?’可以用於字段和字段,表示“沒有具體的值“。它主要用於在這兩個字段的某一箇中指定某個值,更好的理解請參考下面的示例(以及CrontTrigger的JavaDoc)。

字符’L’可以用於字段和字段,它是last的縮寫,但是用於這兩個字段時,含義並不相同。比如,“L”用於子段,表示“這個月的最後一天” - 即一月的第31天,非閏年二月的第28天。如果‘L’單獨用於字段,它的含義就是“7”或者“SAT”。但是,如果‘L’用於字段時,前面還有一個值,則表示“這個月的最後一個周××” - 比如,“6L”或“FRIL”表示“這個月的最後一個週五”。我們也可以指定與這個月最後一天的偏移量,比如“L-3”表示與這個月的最後一天相差3天。需要注意的是,如果使用選項‘L’,則不要使用列舉和範圍,否則結果將是不可預料的。

字符’W’表示離某一天最近的工作日(weekday)。例如,字段上的值“15W”表示“離這個月的15號最近的工作日”。

字符’#’表示“這個月的第n個周××”。例如,在字段上的“6#3”或“FRI#3”表示“這個月的3個週五”。

以下爲一些表達式的例子及對應的含義 - 在org.quartz.CronExpression的JavaDoc有更多的描述。

Cron表達式示例

CronTrigger示例1 - 每隔5分鐘執行一次:

0 0/5 * * * ?

CronTrigger示例2 - 每隔5分鐘,且在該分鐘的第10秒執行(如10:00:10 am, 10:05:10 am等):

10 0/5 * * * ?

CronTrigger示例3 - 每週三和週五的10:30, 11:30, 12:30和13:30執行:

0 30 10-13 ? * WED,FRI

Crontrigger示例4 - 在每個月的第5天和第20天,上午8點到上午10點之間每隔半小時執行。注意:該trigger不會在上午10點執行,只在上午8:00, 8:30, 9:00和9:30執行:

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

提示一下,有些調度需求太複雜了,無法使用一個trigger表達 - 比如:“在上午9點和上午10點之間,每隔5分鐘執行一次,且在下午1點到下午10點之間每隔20分鐘執行一次”。應對這樣的需求,可以創建兩個trigger,註冊到同一個job上即可。

創建CronTrigger

CronTrigger實例可以通過TriggerBuilder(配置主要屬性)和CronScheduleBuilder(配置CronTrigger專有的屬性)配置。爲了以DSL風格使用這些builder,需要靜態導入:

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

構建一個trigger,在每天的上午8點到下午5點之間每隔2分鐘執行一次,如:

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

構建一個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();

構建一個trigger,在每週三的上午10:42執行,並配置TimeZone:

trigger = newTrigger()
 .withIdentity("trigger3", "group1")
   .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42)
      .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles")))
 .forJob(myJobKey)
 .build();

或者:

trigger = newTrigger()
 .withIdentity("trigger3", "group1")
   .withSchedule(cronSchedule("0 42 10 ? * WED")
     .inTimeZone(TimeZone.getTimeZone("America/Los_Angeles")))
 .forJob(myJobKey)
 .build();

CronTriggter錯過觸發策略

下面的這些策略用於告訴Quartz,如果CronTrigger錯過觸發時應該採取的處理方式。(關於錯過觸發的場景,在本教程的Trigger介紹部分以經介紹過)。這些策略值是定義在CronTrigger上的常量,包括:

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW

所有的trigger都可以使用Trigger.MISFIRE_INSTRUCTION_SMART_POLICY策略,該策略也是所有trigger的默認策略。在CronTrigger中,smart policy策略其實就是MISFIRE_INSTRUCTION_FIRE_NOW. CronTrigger.updateAfterMisfire()的API文檔中對該策略有更詳細的解釋。

在構造CronTrigger時,將錯過觸發策略作爲調度的一部分進行配置(通過CronScheduleBuilder):

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

轉載地址 http://nkcoder.xyz/2018/01/20/quartz-tutorial-06-crontrigger/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章