(翻译)Quartz官方教程——第四课:关于触发器

与任务一样,触发器也十分易于使用,但是仍包含了定制的选项,在你充分利用Quartz之前你需要了解和理解它们。另外,如前所述,您可以选择不同类型的触发器来满足不同的调度需求。

您将在第5课:简单触发器和第6课:Cron触发器中了解两种最常见类型的触发器。

通用触发器属性

除了所有触发器类型都具有用于跟踪其身份的TriggerKey属性之外,还有一些其他属性对所有触发器类型都是通用的。这些常用属性是在构建触发器定义时使用TriggerBuilder设置的(后面将举例说明)。

以下是所有触发器类型共有的属性列表:

  • “jobKey”属性表示触发器触发时应执行的作业的标识。
  • “startTime”属性表示触发器的计划何时首次生效。该值是一个java.util.Date对象,它定义给定日历日期的时间。对于某些触发类型,触发器实际上会在开始时触发,对于其他触发器,它只是标记调度器应该开始跟踪的时间。这意味着您可以在一月存储具有诸如“每个月的第五天”的触发器,并且如果startTime属性设置为4月1日,则将在第一次触发前几个月存在。
  • “endTime”属性指示触发器的时间表何时不再有效。换句话说,一个时间表“每个月的第五天”和7月1日结束时间的触发器将在6月5日最后一次触发。

其它需要更多解释的属性将在下边讨论。

优先级(Priority)

有时候,当你有很多触发器(或者你的Quartz线程池中有很少的工作线程),Quartz可能没有足够的资源立即触发这些将同时运行的触发器。在这种情况下,你可能想要控制哪些触发器首先运行。为此,您可以在触发器上设置优先级属性。如果N个触发器同时触发,但当前只有Z个工作线程可用,则首先执行具有最高优先级的Z个触发器。如果您没有在触发器上设置优先级,那么它将使用默认优先级5。任何整数值都允许优先级,包括正值或负值。

注意:仅当触发器具有相同的触发时间时才比较优先级。计划在10:59触发的触发器始终早于计划在11:00触发的计划触发。

注意:当检测到触发器的作业需要恢复时,其恢复计划的优先级与原始触发器相同。

Misfire Instructions

触发器的另一个重要属性是“misfire instruction”。如果由于调度程序关闭而导致持续触发器“遗漏”其触发时间,或者由于Quartz的线程池中没有可用的线程来执行作业,则会发生misfire。不同的触发器类型有着不同的misfire策略。默认情况下它们使用“智能策略”—— 基于触发类型和配置的动态行为。当调度器启动时,它会搜索错过执行的持久化触发器,然后根据它们配置的mifire策略进行更新。当你在项目中使用Quartz时,你需要熟悉各个触发器类型的mifire策略。关于mifire策略的更多具体信息将在针对每种触发类型的教程课程中给出。

日历(Calendars)

Quartz的Calendar对象(而不是 java.util.Calendar对象)可以在触发器定义时与其关联起来并存储在调度器中。日历对于从触发事件表中排除时间块很有用。举个栗子,您可以创建一个触发器,在上午9:30的每个工作日触发一项任务,但添加一个排除所有业务假期的日历。

日历可以是任何实现Calendar接口的可序列化对象,Calendar接口如下所示:

package org.quartz;

public interface Calendar {

  public boolean isTimeIncluded(long timeStamp);

  public long getNextIncludedTime(long timeStamp);

}

注意这些方法的参数是长整形的。你可能会猜到,它们是毫秒格式的时间戳。这意味着日历可以将时间段缩短到毫秒级。但更可能的是,你对排除整天更感兴趣。为了方便起见,Quartz包含了org.quartz.impl.HolidayCalendar类,它就是这样做的。

日历必须被初始化并且通过addCalendar()方法加入到调度器。如果你使用HolidayCalendar,你需要使用它的addExcludedDate(Date date)方法来排序那些你想要排除的日期。相同的日历实例可以与多个触发器一起使用,如下所示:

HolidayCalendar cal = new HolidayCalendar();
cal.addExcludedDate( someDate );
cal.addExcludedDate( someOtherDate );

sched.addCalendar("myHolidays", cal, false);


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

触发器的构建/构建细节将在接下来的几节课中给出。现在,只要相信上面的代码会创建两个触发器,每个触发器都计划每天触发一次。但是,在日历排除的期间内发生的任何触发都将被跳过。

请参阅org.quartz.impl.calendar软件包了解适合您需求的多个Calendar实现。

猜你喜欢

转载自my.oschina.net/icebergxty/blog/1797986
今日推荐