1. 程式人生 > >Lesson 5: SimpleTrigger

Lesson 5: SimpleTrigger

http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-05.html

SimpleTrigger should meet your scheduling needs if you need to have a job execute exactly once at a specific moment in time, or at a specific moment in time followed by repeats at a specific interval. For example, if you want the trigger to fire at exactly 11:23:54 AM on January 13, 2015, or if you want it to fire at that time, and then fire five more times, every ten seconds.

With this description, you may not find it surprising to find that the properties of a SimpleTrigger include: a start-time, and end-time, a repeat count, and a repeat interval. All of these properties are exactly what you’d expect them to be, with only a couple special notes related to the end-time property.

The repeat count can be zero, a positive integer, or the constant value SimpleTrigger.REPEAT_INDEFINITELY. The repeat interval property must be zero, or a positive long value, and represents a number of milliseconds. Note that a repeat interval of zero will cause ‘repeat count’ firings of the trigger to happen concurrently (or as close to concurrently as the scheduler can manage).

If you’re not already familiar with Quartz’s DateBuilder class, you may find it helpful for computing your trigger fire-times, depending on the startTime (or endTime) that you’re trying to create.

The endTime property (if it is specified) overrides the repeat count property. This can be useful if you wish to create a trigger such as one that fires every 10 seconds until a given moment in time - rather than having to compute the number of times it would repeat between the start-time and the end-time, you can simply specify the end-time and then use a repeat count of REPEAT_INDEFINITELY (you could even specify a repeat count of some huge number that is sure to be more than the number of times the trigger will actually fire before the end-time arrives).

如果你需要在一個指定時間段內執行一次作業任務或是在指定的時間間隔內多次執行作業任務,SimpleTrigger應該能滿足你的排程需求。例如,你希望觸發器在2015年1月13日上午11:23:54準時觸發,或是希望在那個時間點觸發,然後再重複觸發5次,每隔10秒一次。

有了這樣的描述,你就不會對SimpleTrigger包含的引數感到奇怪:開始執行時間,結束執行時間,重複次數和重複執行間隔時間。所有的引數都是你期望的那樣,只是關於結束執行時間引數有兩條特別的提示。

 重複次數可以為0,正整數或是SimpleTrigger.REPEAT_INDEFINITELY常量值。重複執行間隔必須為0或長整數(long型別),它表示毫秒數的值。注意如果重複執行間隔時間為0會導致數量為“重複次數”的觸發器併發執行(或是在排程器控制下接近併發執行)。

    如果你還不熟悉Quartz的DateBuilder類,你嘗試建立日期物件時會發現它非常方便地根據startTime或 endTime引數計算觸發器的觸發時間。

EndTime引數(如果被指定)會覆蓋重複次數引數的效果。當你希望建立一個觸發器,每隔10秒被觸發一次直到給定的截止時間,而不是必須完成在給定的開始和結束時間段內的觸發次數,使用endTime引數會非常方便,你可以僅僅指定一個end-time引數,並且將重複次數設定為REPEAT_INDEFINITELY(你甚至可以將重複次數指定為非常大的值,確保比結束執行時間到達前實際要執行的次數大就行)。


SimpleTrigger instances are built using TriggerBuilder (for the trigger’s main properties) and SimpleScheduleBuilder (for the SimpleTrigger-specific properties). To use these builders in a DSL-style, use static imports:

SimpleTrigger例項通過TriggerBuilder(for the trigger’s main properties)和SimpleScheduleBuilder(for the SimpleTrigger-specific properties)建立,通過如下程式碼匯入他們的靜態方法:

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

Here are various examples of defining triggers with simple schedules, read through them all, as they each show at least one new/different point:

下面是一些defining triggers with simple schedules的例子,可以從中比較他們的異同:

Build a trigger for a specific moment in time, with no repeats:

建立一個不會重複的在指定時間執行的trigger


SimpleTrigger trigger = (SimpleTrigger) newTrigger()
    .withIdentity("trigger1", "group1")
    .startAt(myStartTime) // some Date
    .forJob("job1", "group1") // identify job with name, group strings
    .build();
Build a trigger for a specific moment in time, then repeating every ten seconds ten times:

建立一個每10分鐘執行一次、執行10次、在指定時間執行的trigger

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


Build a trigger that will fire once, five minutes in the future:

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

Build a trigger that will fire now, then repeat every five minutes, until the hour 22:00:

建立一個立馬執行的trigger, 每五分鐘重複一次, 一直到 22:00:


trigger = newTrigger()
    .withIdentity("trigger7", "group1")
    .withSchedule(simpleSchedule()
        .withIntervalInMinutes(5)
        .repeatForever())
    .endAt(dateOf(22, 0, 0))
    .build();
Build a trigger that will fire at the top of the next hour, then repeat every 2 hours, forever:

建立一個trigger會在下一個小時的0分0秒執行,然後是一直是每兩個小時執行一次

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

Spend some time looking at all of the available methods in the language defined by TriggerBuilder and SimpleScheduleBuilder so that you can be familiar with options available to you that may not have been demonstrated in the examples above.

熟悉TriggerBuilderSimpleScheduleBuilder定義的一些方法,還可以發現一些其他上面的例子中沒有列舉出來的選項。

Note that TriggerBuilder (and Quartz's other builders) will generally choose a reasonable value for properties that you do not explicitly set. For examples: if you don't call one of the *withIdentity(..)* methods, then TriggerBuilder will generate a random name for your trigger; if you don't call *startAt(..)* then the current time (immediately) is assumed.
另外, TriggerBuilder (以及quartz其他的builders) ,在你沒有明確的為一些屬性指定值的時候,builder會將其設定為一些有意義的值。比如沒有設定 withIdentity() 方法的值時候, TriggerBuilder 會為你的trigger生成一個隨機的名字;如果沒有呼叫 startAt() 那預設就是當前的時間。


SimpleTrigger Misfire Instructions

SimpleTrigger has several instructions that can be used to inform Quartz what it should do when a misfire occurs. (Misfire situations were introduced in “Lesson 4: More About Triggers”). These instructions are defined as constants on SimpleTrigger itself (including JavaDoc describing their behavior). The instructions include:

Misfire Instruction Constants of SimpleTrigger

SimpleTrigger 有一些instructions 可以通知quartz在misfire 出現的時候告訴quartz應該做些什麼。這些instructionsSimpleTrigger 有對應的常量定義(可以參閱JavaDoc文件)。這些instructions 包括:

SimpleTrigger中的Misfire Instruction 常量

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

You should recall from the earlier lessons that all triggers have the Trigger.MISFIRE_INSTRUCTION_SMART_POLICY instruction available for use, and this instruction is also the default for all trigger types.

If the ‘smart policy’ instruction is used, SimpleTrigger dynamically chooses between its various MISFIRE instructions, based on the configuration and state of the given SimpleTrigger instance. The JavaDoc for the SimpleTrigger.updateAfterMisfire() method explains the exact details of this dynamic behavior.

When building SimpleTriggers, you specify the misfire instruction as part of the simple schedule (via SimpleSchedulerBuilder):

在先前文章中使用的triggers都預設使用了Trigger.MISFIRE_INSTRUCTION_SMART_POLICY instruction, 這是預設的instruction對於所有的trigger型別來說。

如果smart policy instruciton被使用了,SimpleTrigger會基於configuration和SimpleTrigger instancestate動態的從各種MISFIRE instructions 中選取合適的。可以檢視SimpleTrigger.updateAfterMisfire()的JavaDoc文件,詳細描述了動態行為的細節。

通過SimpleSchedulerBuilder的simpleSchedule指定misfire instruction:


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