第六課 CronTriggerui
CronTrigger比SimpleTrigger更經常使用,當你須要一個基於日曆般概念的做業調度器,而不是像SimpleTrigger那樣精確指定間隔時間。
使用SimpleTrigger,你能夠這樣指定觸發時間表例如「每週五的中午」,或是「每週末的上午9:30」,甚至是「一月份每週1、3、五上午9:00到10:00之間每5分鐘」。
雖然如此,跟SimpleTrigger同樣,CronTrigger也須要指定startTime讓調度器生效,指定endTime讓調度器終止。spa
Cron表達式
Cron表達式用於配置CronTrigger實例。Cron表達式其實是由7個子表達式組成的字符串,描述了時間表的詳細信息。這些子表達式用空格隔開,分別表明:設計
一、秒
二、分
三、小時
四、月份中的天數
五、月
六、星期中的天數
七、年(可選)
一個完整的Cron表達式的字符串例子「0 0 12 ? * WED」,意思是「每週三的上午12:00:00」。
code
每一個了表達式都包含「和」、「或」的兩種排列,例如,上一個例子中星期中的天數字段(顯示的是「WED」)能夠替換爲「MON-FRI」,「MON,WED,FRI」,甚至是「MON-WED,SAT」。
通配符(「*」)可用來表示該字段的任意值,所以「*」在上面的例子中的月份字段表示「每月」,「*」在星期中的天數字段由此明顯是表示「一週的任何一天」。對象
「/」字符可用來表示增量的值。例如,若是你在分鐘字段寫「0/15」,這表示「每次從一小時中的第0分鐘開始,每隔15分鐘觸發」,若是你在分鐘字段上寫「3/20」,這表示「每次從一小時中的第3分鐘開始,每隔20分鐘觸發」——換句話說,這跟在分鐘字段上指定「3,23,43」是同樣的。注意細微的區別:「/35」不是表示「每隔35分鐘」,而是表示「每次從一小時中的第0分鐘開始,每隔35分鐘觸發」,至關於指定「0,35」。
blog
「?」字符容許出如今月份中的天數和星期中的天數字段中。它通常用來指定「不關心的值」。當你須要在這兩個字段中的一個指定不肯定的值是很是方便的,這個字符不能用在其餘的字段中。能夠查看下面的例子(或是CronTrigger的)得到更詳細的說明。文檔
「L」字符容許出如今月份中的天數和星期中的天數字段中。這個字符是「last」的縮寫,可是在這兩個字段中有不一樣的含義。例如,「L」字符出如今月份中的天數字段中表示「每個月的最後一天」——1月31日,平年的2月28日。若是該字符單獨用在星期中的天數字段時,僅僅是表示「7」或是「SAT」。可是在星期中的天數字段中該字符用在其餘值的後面,表示「每個月的最後一個星期幾」——例如「6L」或是「FRIL」都表示「每個月的最後一個星期五」。你也能夠指定每個月最後一天的偏移數,例如「L-3」表示日曆月份的最後三天。當你使用「L」字符時,最好不要使用排列值或是帶範圍的值,不然你會對結果感到意外和難以理解。字符串
「w」字符用來指定給定日期的最近一個工做日(工做日指的是從週一到週五)。例如,若是你在月份中的天數字段的值指定爲「15w」,這表示「離每個月15號最近的工做日」。
「#」字符用來指定每個月的第N個工做日,例如,星期中的天數字段的值爲「6#3」或是「FRI#3」表示「每個月的第三個星期五」。it
下面演示了一些表達式的例子和含義——你能夠在org.quartz.CronExpression的找到更多信息。io
Cron表達式案例
Cron案例1——僅僅表示每隔5分鐘觸發一次:
"00/5 * * * ?"
Cron案例2——表示每隔5分鐘,在過了10秒後觸發一次(例如上午10:00:10,10:05:10等):
"100/5 * * * ?"
Cron案例3——表示每一個週三到週五,在上午10:30,11:30,12:30和13:30分觸發:
"030 10-13 ? * WED,FRI"
Cron案例4——表示每個月從5號到20號,上午8時到10時之間的每半小時觸發,注意這個觸發器只在8:00,8:30,9:00和9:30分觸發,上午10:00不會觸發:
"00/30 8-9 5,20 * ?"
注意有些調度需求因太複雜例如「上午9:00到10:00之間的每5分鐘,下午1:00到10:00的每20分鐘」,而不能用單一的觸發器來表示。這種狀況的解決方案是建立兩個簡單的觸發器,將它們註冊到調度器中去運行同一個做業任務。
構建CronTriggers
CronTrigger實例對象可使用TriggerBuilder(針對 觸發器主要的參數)和CronScheduleBuilder(針對CronTrigger的指定參數)來建立。爲了使用這些建立類時知足DSL格式,使用靜態導入:
建立一個觸發器,天天從上午8點到下午5點,每隔2分鐘觸發一次:
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger3", "group1") 3 .WithCronSchedule("0 0/2 8-17 * * ?") 4 .ForJob("myJob", "group1") 5 .Build();
建立一個觸發器,天天的上午10:42分觸發一次:
1 // we use CronScheduleBuilder's static helper methods here 2 trigger = TriggerBuilder.Create() 3 .WithIdentity("trigger3", "group1") 4 .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(10, 42)) 5 .ForJob(myJobKey) 6 .Build();
或者
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger3", "group1") 3 .WithCronSchedule("0 42 10 * * ?") 4 .ForJob("myJob", "group1") 5 .Build();
CronTrigger觸發失敗指令
CronTrigger有幾條指令,用來告知Quartz當觸發失敗時該如何操做。(在第四課更多關於觸發器已經介紹過觸發失敗的狀況)。這些指令在CronTrigger類中設計成常量(包含JavaDoc描述了它們的行爲)。指令有:
CronTrigger的觸發失敗指令常量
•MisfireInstruction.IgnoreMisfirePolicy
•MisfireInstruction.CronTrigger.DoNothing
•MisfireInstruction.CronTrigger.FireOnceNow
全部的觸發器均可以使用Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令,而且這條指令也是全部觸發器的默認指令。
「智能策略」指令能夠從CronTrigger的MISFIRE_INSTRUCTION_FIRE_NOW當中得到解釋。文檔中CronTrigger的updateAfterMisfire方法解釋了動態選擇行爲的更詳細的信息。
當你建立CronTrigger時,能夠經過CronSchedulerBuilder指令觸發失敗指令做爲調度器的一部分。
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger3", "group1") 3 .WithCronSchedule("0 0/2 8-17 * * ?", x => x 4 .WithMisfireHandlingInstructionFireAndProceed()) 5 .ForJob("myJob", "group1") 6 .Build();