Quartz使用(3) - Quartz核心接口Trigger

Trigger最經常使用的有兩種SimpleTrigger和CronTrigger,首先介紹Trigger的一些基礎的信息,而後會詳細描述這兩種Trigger。ide

1. 通用Trigger屬性

quartz中全部的觸發器Trigger都有一些共有屬性,如TriggerKey,startTime等,這些屬性可使用TriggerBuilder進行設置。經常使用的屬性舉例以下:ui

(1) triggerKey:觸發器的標識,由名稱與分組惟一指定,便於調度器調用與查找。this

(2) jobKey: 當觸發器被觸發時,標識哪個任務Job應該被執行。spa

(3) startTime: 表示觸發器第一次開始觸發的時間。線程

(4) endTime: 表示觸發器終止觸發的時間。code

2. 優先級

當存在多個觸發器時,quartz可能沒有足夠的資源當即觸發全部配置爲同一時間觸發的triggers,所以能夠設置每一個Trigger的優先級。默認的優先級爲5,可取任意的整型值,包括正數或負數。注意優先級僅用於全部相同時間觸發的triggers對象

3. 未啓動指令"Misfire  Instructions"

Trigger未觸發通常產生於調度器被關閉,或線程池不足時。不一樣的Trigger類型有不一樣的未啓動指令。默認的,他們會使用"smart policy"指定。這些指令的使用場景在於,當scheduler開啓時,它將搜索全部未啓動的持久化的觸發器,而後基於觸發器各自配置"未啓動指令"來更新觸發器。未啓動指令用於當trigger未正常觸發時,是否恢復執行的場景。blog

4. Calendars

與Trigger關聯的Calendar對象,用於在指定的時間內不觸發trigger,例如你有一個任務天天執行一次,但你不但願在節假日執行時,Calendar此時派上用場。注意此Calendar爲quartz自身的定義接口,而非Java自帶的Calendar。接口

Calendar須要在Scheduler定義過程當中,經過scheduler.addCalendar()進行初始化和註冊。ci

示例:

import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
Trigger t = newTrigger()
    .withIdentity("myTrigger")
    .forJob("myJob")
    .withSchedule(dailyAtHourAndMinute(9, 30)) // execute job daily at 9:30
    .modifiedByCalendar("myHolidays") // but not on holidays
    .build();

// .. schedule job with trigger

Trigger t2 = newTrigger()
    .withIdentity("myTrigger2")
    .forJob("myJob2")
    .withSchedule(dailyAtHourAndMinute(11, 30)) // execute job daily at 11:30
    .modifiedByCalendar("myHolidays") // but not on holidays
    .build();

// .. schedule job with trigger2
View Code

 5. SimpleTrigger

 當須要在規定時間執行一次或在規定的時間段以必定的時間間隔重複觸發執行Job時,SimpleTrigger就能夠知足。

SimpleTrigger的屬性有:開始時間、結束時間、重複次數和重複的時間間隔。重複次數屬性的值能夠爲0、正整數、或常量 SimpleTrigger.REPEAT_INDEFINITELY,重複的時間間隔屬性值必須爲0或長整型的正整數,以毫秒做爲時間單位,當重複的時間間隔爲0時,意味着與Trigger同時觸發執行。若是有指定結束時間屬性值,則結束時間屬性優先於重複次數屬性,這樣的好處在於:當咱們須要建立一個每間隔10秒鐘觸發一次直到指定的結束時間的 Trigger,而無需去計算從開始到結束的所重複的次數,咱們只需簡單的指定結束時間和使用REPEAT_INDEFINITELY做爲重複次數的屬性 值便可。

 示例:

(1) 建立在特定時間觸發,非重複的Trigger

import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.DateBuilder.*:
SimpleTrigger trigger = (SimpleTrigger) newTrigger()
    .withIdentity("trigger1", "group1")
    .startAt(myStartTime) // some Date
    .forJob("job1", "group1") // identify job with name, group strings
    .build();
View Code

(2) 建立在特定時間觸發,重複間隔爲10次,重複執行10次的Trigger

import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.DateBuilder.*:
trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .startAt(myTimeToStartFiring)  // if a start time is not given (if this line were omitted), "now" is implied
    .withSchedule(simpleSchedule()
        .withIntervalInSeconds(10)
        .withRepeatCount(10)) // note that 10 repeats will give a total of 11 firings
    .forJob(myJob) // identify job with handle to its JobDetail itself                   
    .build();
View Code

(3) 建立5分鐘後執行,且觸發一次的Trigger

trigger = (SimpleTrigger) newTrigger()
    .withIdentity("trigger5", "group1")
    .startAt(futureDate(5, IntervalUnit.MINUTE)) // use DateBuilder to create a date in the future
    .forJob(myJobKey) // identify job with its JobKey
    .build();
View Code

(4) 建立當即執行,且重複間隔爲5分鐘,到22點結束的Trigger

trigger = newTrigger()
    .withIdentity("trigger7", "group1")
    .withSchedule(simpleSchedule()
        .withIntervalInMinutes(5)
        .repeatForever())
    .endAt(dateOf(22, 0, 0))
    .build();
View Code

(5) 建立在下一小時觸發,且每2小時執行重複執行的Trigger

trigger = newTrigger()
    .withIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group
    .startAt(evenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00"))
    .withSchedule(simpleSchedule()
        .withIntervalInHours(2)
        .repeatForever())
    // note that in this example, 'forJob(..)' is not called
    //  - which is valid if the trigger is passed to the scheduler along with the job  
    .build();

    scheduler.scheduleJob(trigger, job);
View Code

SimpleTrigger的未啓動指令包含以下:

MISFIRE_INSTRUCTION_SMART_POLICY
MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY MISFIRE_INSTRUCTION_FIRE_NOW MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

構件SimpleTrigger的時候,能夠指定Trigger的未啓動指令:

trigger = newTrigger()
    .withIdentity("trigger7", "group1")
    .withSchedule(simpleSchedule()
        .withIntervalInMinutes(5)
        .repeatForever()
        .withMisfireHandlingInstructionNextWithExistingCount())
    .build();
View Code

 

6. CronTrigger 

6.1 cron表達式

CronTrigger 支持比SimpleTrigger更具體、更復雜的調度。基於cron表達式,CronTrigger支持相似日曆的重複間隔,而非單一的時間間隔。

序號 說明 是否必填 容許填寫的值 容許的通配符
1 0-59 , - * /
2 0-59 , - * /
3 小時 0-23 , - * /
4 1-31  , - * ? / L W
5 1-12或JAN-DEC , - * /
6 1-7或SUN-SAT , - * ? / L #
7 空或1999-2017 , - * /

通配符的說明:

(1) 反斜線(/)字符表示增量值。例如,在秒字段中「5/15」表明從第 5 秒開始,每 15 秒一次。

(2) 星號(*)字符是通配字符,表示該字段能夠接受任何可能的值,例如:在分的字段上設置 "*",表示每一分鐘都會觸發。

(3) 問號(?)問號表示這個字段不包含具體值。若是指定月內日期,能夠在月內日期字段中插入「?」,表示周內日期值可有可無。

(4) -  表示區間,例如 在小時上設置 "10-12",表示 10,11,12點都會觸發。

(5) 逗號(, ) 表示指定多個值,例如在周字段上設置 "MON,WED,FRI" 表示週一,週三和週五觸發。

(6) 井號(#)字符爲給定月份指定具體的工做日實例。把「MON#2」放在周內日期字段中,表示把任務安排在當月的第二個星期一。

(7) L 表示最後的意思。在日字段設置上,表示當月的最後一天(依據當前月份,若是是二月還會依據是不是潤年[leap]), 在周字段上表示星期六,至關於"7"或"SAT"。若是在"L"前加上數字,則表示該數據的最後一個。例如在周字段上設置"6L"這樣的格式,則表示「本月最後一個星期五"。

(8) W 表示離指定日期的最近那個工做日(週一至週五). 例如在日字段上設置"15W",表示離每個月15號最近的那個工做日觸發。若是15號正好是週六,則找最近的週五(14號)觸發, 若是15號是周未,則找最近的下週一(16號)觸發.若是15號正好在工做日(週一至週五),則就在該天觸發。若是指定格式爲 "1W",它則表示每個月1號日後最近的工做日觸發。若是1號正是週六,則將在3號下週一觸發。(注,"W"前只能設置具體的數字,不容許區間"-")。

注:'L'和 'W'能夠組合使用。若是在日字段上設置"LW",則表示在本月的最後一個工做日觸發。

cron表達式的舉例以下:

0 10 * * * ?--------------每一個小時過10分執行一次
0 0/32 8,12 * * ? ----------天天8:32,12:32 執行一次
0 0/2 * * * ?--------------每2分鐘執行一次
0 0 12 * * ?---------------在天天中午12:00觸發 
0 15 10 ? * *---------------天天上午10:15 觸發 
0 15 10 * * ?---------------天天上午10:15 觸發 
0 15 10 * * ? *---------------天天上午10:15 觸發 
0 15 10 * * ? 2005---------------在2005年中的天天上午10:15 觸發 
0 * 14 * * ?---------------天天在下午2:00至2:59之間每分鐘觸發一次 
0 0/5 14 * * ?---------------天天在下午2:00至2:59之間每5分鐘觸發一次 
0 0/5 14,18 * * ?---------------天天在下午2:00至2:59和6:00至6:59之間的每5分鐘觸發一次 
0 0-5 14 * * ?---------------天天在下午2:00至2:05之間每分鐘觸發一次 
0 10,44 14 ? 3 WED---------------每三月份的星期三在下午2:00和2:44時觸發 
0 15 10 ? * MON-FRI---------------從星期一至星期五的天天上午10:15觸發 
0 15 10 15 * ?---------------在每月的每15天的上午10:15觸發 
0 15 10 L * ?---------------在每月的最後一天的上午10:15觸發 
0 15 10 ? * 6L---------------在每月的最後一個星期五的上午10:15觸發 
0 15 10 ? * 6L 2002-2005---------------在2002, 2003, 2004 and 2005年的每月的最後一個星期五的上午10:15觸發 
0 15 10 ? * 6#3---------------在每月的第三個星期五的上午10:15觸發 
0 0 12 1/5 * ?---------------從每個月的第一天起每過5天的中午12:00時觸發 
0 11 11 11 11 ?---------------在每一個11月11日的上午11:11時觸發
View Code

6.2 CronTrigger構建

可使用TriggerBuilder 來定義CronTrigger對象。示例以下:

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

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?"))
    .forJob("myJob", "group1")
    .build();
    
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 = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(weeklyOnDayAndHourAndMinute(DateBuilder.WEDNESDAY, 10, 42))
    .forJob(myJobKey)
    .inTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))
    .build();

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

6.3 CronTrigger Misfire Instruction

CronTrigger的未啓動指令包含:

MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY
MISFIRE_INSTRUCTION_DO_NOTHING
MISFIRE_INSTRUCTION_FIRE_NOW
MISFIRE_INSTRUCTION_SMART_POLICY

未啓動指令的使用:

trigger = newTrigger()
    .withIdentity("trigger3", "group1")
    .withSchedule(cronSchedule("0 0/2 8-17 * * ?")
        .withMisfireHandlingInstructionFireAndProceed())
    .forJob("myJob", "group1")
    .build();
View Code
相關文章
相關標籤/搜索