Quartz_2.2.X学习系列五:Tutorials - Lesson 5: SimpleTrigger

简单的触发器(SimpleTrigger)

一、 适合场景:

1.在某个特定的时间点执行一次任务。

2.在某个特定的时间点开始执行任务,然后每间隔N时长执行一次(“重复间隔”属性设置),一共执行M(“重复次数”属性设置)次。

 

二、一个简单触发器的属性包括:开始时间、结束时间、重复次数和重复间隔。

1.“重复次数”属性:可以是零,一个正整数,或者常量值(SimpleTrigger.REPEAT_INDEFINITELY,一直重复到endTime为止)。

2.“重复间隔”属性:必须为零,或一个正数,表示为几毫秒的时间(虽然我们可以用时,分,秒来设,但实际上Quartz会将它转为毫秒)。

 

注意:重复触发间隔时间为零将导致触发器所设置的“重复次数”将被同时触发(或者它接近于调度程序可管理的并发现象),即如果设置触发器的触发次数为5,间隔时间为0,则5次会同时触发。

 

3.startTime属性:表明触发器的schedule何时开始生效。

4.endTime属性:(如果指定的话)会覆盖“重复次数”属性。如果您希望创建一个触发器(每10秒触发一次),直到一个给定的时刻时中止。而不是要达到触发的次数才停止,即它将在“开始时间”与“结束时间”之间按触发频率来触发任务。

 

三、DSL风格的写法

SimpleTrigger实例是使用trigger builder(针对触发器的主要属性)和SimpleScheduleBuilder(针对简单的触发器特有的属性)来构建的。使这些Builder要使用dsl风格的写法,并要事先静态导入:

 

import static org.quartz.TriggerBuilder.*;

import static org.quartz.SimpleScheduleBuilder.*;

import static org.quartz.DateBuilder.*:

 

四、默认值

默认值:对于我没有明确的设置属性值,则Quartz会自动设置它们的默认值

请注意,trigger builder(以及Quartz的其他builders)通常会为您没有显式设置的属性选择一个合理的值,例如:如果您不调用withIdentity(..)*中某个方法,那么trigger builder将为您的触发器生成一个随机名称;如果你不调用startAt(..)*,那么当前时间(立即)被假定。

 

五、简单触发器激发失败指令(SimpleTrigger Misfire Instructions)

这些指令被定义在SimpleTrigger本身的常量中(详见SimpleTrigger源码)

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

 

Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令可供使用,该指令是所有触发器类型的默认值。

 

使用“智能策略”指令被使用,SimpleTrigger会动态的在它的多个MISFIRE指令之间选择。基于给定的 SimpleTrigger的实例的配置与状态。在JavaDoc中关于simpletrigger.updateaftermisfire()方法解释了这种动态行为的确切细节。

 

在构建SimpleTriggers时,您可以指定misfire指令作为简单调度的一部分(通过SimpleSchedulerBuilder)

 

 

Lesson 5: SimpleTrigger

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.

 

如果您需要在特定的时间点上执行一次任务,或者在特定的时间,按指定的时间间隔执行任务,那么SimpleTrigger应该满足您的调度需求。例如,如果你想让触发器在2015年1月13日上午11:23:54,或者你想让它在那个时候触发,然后再触发5次,每10秒一次。

 

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.

 

“重复次数”属性:可以是零,一个正整数,或者常量值(SimpleTrigger.REPEAT_INDEFINITELY)。

Trigger trigger = newTrigger()//

.withRepeatCount(10)) // note that 10 repeats will give a total of 11 firings

Trigger trigger = newTrigger()//

.withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)

 

SimpleTrigger.REPEAT_INDEFINITELY:Used to indicate the 'repeat count' of the trigger is indefinite. Or in other words, the trigger should repeat continually until the trigger's ending timestamp.

 

“重复间隔”属性:必须为零,或一个正数,表示为几毫秒的时间(虽然我们可以用时,分,秒来设,但实际上Quartz会将它转为毫秒)。

.withIntervalInSeconds(10):每10秒执行一次

源码如下:

public SimpleScheduleBuilder withIntervalInSeconds(int intervalInSeconds) {

        this.interval = intervalInSeconds * 1000L;

        return this;

    }

 

.withIntervalInHours(5):每5小时执行一次。

源码如下:

public SimpleScheduleBuilder withIntervalInHours(int intervalInHours) {

        this.interval = intervalInHours * DateBuilder.MILLISECONDS_IN_HOUR;

        return this;

    }

 

 

注意:重复触发间隔时间为零将导致触发器所设置的“重复次数”将被同时触发(或者它接近于调度程序可管理的并发现象),即如果设置触发器的触发次数为5,间隔时间为0,则5次会同时触发。

 

当您还不熟悉Quartz的DateBuilder类时,您可能会发现,这个类对于计算您的触发触的触发时间有帮助,这取决于您想要创建的startTime(或endTime)。

 

startTime属性:表明触发器的schedule何时开始生效。

 

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 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:

 

endTime属性:(如果指定的话)会覆盖“重复次数”属性。如果您希望创建一个触发器(每10秒触发一次),直到一个给定的时刻时中止。而不是要达到触发的次数才停止,即它将在“开始时间”与“结束时间”之间按触发频率来触发任务。

 

您可以简单地指定的“结束时间”,然后使用一个REPEAT_INDEFINITELY重复计数(你甚至可以指定巨大数额的重复计算,以保证在“结束时间”到达之前,“触发器”都有按时间间隔在不断的正常触发执行任务)。

 

SimpleTrigger实例是使用trigger builder(针对触发器的主要属性)和SimpleScheduleBuilder(针对简单的触发器特有的属性)来构建的。使这些Builder要使用dsl风格的写法,并要事先静态导入:

 

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:

 

下面这些是用简单的Schedule来定义触发器的各种例子。通读它们,因为它们每个都显示了至少一个新的或不同的点:

 

Build a trigger for a specific moment in time, with no repeats:
  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:
  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:
  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 = 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 = 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.

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和SimpleScheduleBuilder定义的所有可用的方法,这样您就可以熟悉对你有用的选项,而这些选项可能在上面的示例中没有演示。

请注意,trigger builder(以及Quartz的其他builders)通常会为您没有显式设置的属性选择一个合理的值,例如:如果您不调用withIdentity(..)*中某个方法,那么trigger builder将为您的触发器生成一个随机名称;如果你不调用startAt(..)*,那么当前时间(立即)被假定。

 

TriggerBuilder类的方法:(下面列出一部分,具体的查看源码)

public static TriggerBuilder<Trigger> newTrigger();

public T build();

public TriggerBuilder<T> withIdentity(String name);

public TriggerBuilder<T> withIdentity(String name, String group);

public TriggerBuilder<T> withIdentity(TriggerKey triggerKey);

public TriggerBuilder<T> withDescription(String triggerDescription);

public TriggerBuilder<T> withPriority(int triggerPriority);

public TriggerBuilder<T> modifiedByCalendar(String calName);

public TriggerBuilder<T> startAt(Date triggerStartTime);

 

SimpleScheduleBuilder类的方法:(下面列出一部分,具体的查看源码)

public static SimpleScheduleBuilder repeatMinutelyForever() {

 

        return simpleSchedule()

            .withIntervalInMinutes(1)

            .repeatForever();

    }

 

 public static SimpleScheduleBuilder repeatSecondlyForever() {

 

        return simpleSchedule()

            .withIntervalInSeconds(1)

            .repeatForever();

    }

 

public SimpleScheduleBuilder withIntervalInMinutes(int intervalInMinutes) {

        this.interval = intervalInMinutes * DateBuilder.MILLISECONDS_IN_MINUTE;

        return this;

    }

 

 

 

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:

 

SimpleTrigger 有几个指令,可以用来通知Quartz在发生misfire时应该做什么。(在“第四课”中有介络Misfire的情况)。这些指令被定义在SimpleTrigger本身的常量中(包括描述其行为的JavaDoc)。说明书包括:

 

Misfire Instruction Constants of SimpleTrigger
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

 

----------------------------------------------------------------------------

public interface SimpleTrigger extends Trigger {

 

    public static final long serialVersionUID = -3735980074222850397L;

   

    /**

     * <p>

     * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire

     * situation, the <code>{@link SimpleTrigger}</code> wants to be fired

     * now by <code>Scheduler</code>.

     * </p>

     *

     * <p>

     * <i>NOTE:</i> This instruction should typically only be used for

     * 'one-shot' (non-repeating) Triggers. If it is used on a trigger with a

     * repeat count > 0 then it is equivalent to the instruction <code>{@link #MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT}

     * </code>.

     * </p>

     */

    public static final int MISFIRE_INSTRUCTION_FIRE_NOW = 1;

   

    /**

     * <p>

     * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire

     * situation, the <code>{@link SimpleTrigger}</code> wants to be

     * re-scheduled to 'now' (even if the associated <code>{@link Calendar}</code>

     * excludes 'now') with the repeat count left as-is.  This does obey the

     * <code>Trigger</code> end-time however, so if 'now' is after the

     * end-time the <code>Trigger</code> will not fire again.

     * </p>

     *

     * <p>

     * <i>NOTE:</i> Use of this instruction causes the trigger to 'forget'

     * the start-time and repeat-count that it was originally setup with (this

     * is only an issue if you for some reason wanted to be able to tell what

     * the original values were at some later time).

     * </p>

     */

    public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT = 2;

   

    /**

     * <p>

     * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire

     * situation, the <code>{@link SimpleTrigger}</code> wants to be

     * re-scheduled to 'now' (even if the associated <code>{@link Calendar}</code>

     * excludes 'now') with the repeat count set to what it would be, if it had

     * not missed any firings.  This does obey the <code>Trigger</code> end-time

     * however, so if 'now' is after the end-time the <code>Trigger</code> will

     * not fire again.

     * </p>

     *

     * <p>

     * <i>NOTE:</i> Use of this instruction causes the trigger to 'forget'

     * the start-time and repeat-count that it was originally setup with.

     * Instead, the repeat count on the trigger will be changed to whatever

     * the remaining repeat count is (this is only an issue if you for some

     * reason wanted to be able to tell what the original values were at some

     * later time).

     * </p>

     *

     * <p>

     * <i>NOTE:</i> This instruction could cause the <code>Trigger</code>

     * to go to the 'COMPLETE' state after firing 'now', if all the

     * repeat-fire-times where missed.

     * </p>

     */

    public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT = 3;

   

    /**

     * <p>

     * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire

     * situation, the <code>{@link SimpleTrigger}</code> wants to be

     * re-scheduled to the next scheduled time after 'now' - taking into

     * account any associated <code>{@link Calendar}</code>, and with the

     * repeat count set to what it would be, if it had not missed any firings.

     * </p>

     *

     * <p>

     * <i>NOTE/WARNING:</i> This instruction could cause the <code>Trigger</code>

     * to go directly to the 'COMPLETE' state if all fire-times where missed.

     * </p>

     */

    public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT = 4;

   

    /**

     * <p>

     * Instructs the <code>{@link Scheduler}</code> that upon a mis-fire

     * situation, the <code>{@link SimpleTrigger}</code> wants to be

     * re-scheduled to the next scheduled time after 'now' - taking into

     * account any associated <code>{@link Calendar}</code>, and with the

     * repeat count left unchanged.

     * </p>

     *

     * <p>

     * <i>NOTE/WARNING:</i> This instruction could cause the <code>Trigger</code>

     * to go directly to the 'COMPLETE' state if the end-time of the trigger

     * has arrived.

     * </p>

     */

    public static final int MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT = 5;

   

    /**

     * <p>

     * Used to indicate the 'repeat count' of the trigger is indefinite. Or in

     * other words, the trigger should repeat continually until the trigger's

     * ending timestamp.

     * </p>

     */

    public static final int REPEAT_INDEFINITELY = -1;

----------------------------------------------------------------------------

 

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

 

你应该回想一下之前的课件,所有的触发器都有Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令可供使用,并且该指令也是所有触发器类型的默认值。

如果使用“智能策略”指令被使用,SimpleTrigger会动态的在它的多个MISFIRE指令之间选择。基于给定的 SimpleTrigger的实例的配置与状态。在JavaDoc中关于simpletrigger.updateaftermisfire()方法解释了这种动态行为的确切细节。

在构建SimpleTriggers时,您可以指定misfire指令作为简单调度的一部分(通过SimpleSchedulerBuilder):

 

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

 

 

源码如下:实际调用的是SimpleTrigger类的常量

-----------------------------------------------------------------------

 /**

     * If the Trigger misfires, use the

     * {@link SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT} instruction.

     *

     * @return the updated SimpleScheduleBuilder

     * @see SimpleTrigger#MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT

     */

    public SimpleScheduleBuilder withMisfireHandlingInstructionNextWithExistingCount() {

        misfireInstruction = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT;

        return this;

    }

 

 

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

猜你喜欢

转载自blog.csdn.net/arnolian/article/details/82528065