Quartz教程 第4课 Trigger详解

来源:互联网 发布:鹰身女郎知乎 编辑:程序博客网 时间:2024/06/05 06:32

4课 Trigger详解

跟作业任务类似,触发器也非常容易使用,但是在你能够充分掌握Quartz之前,你需要知道并理解许多自定义选项。前面已经提到过,有许多不同类型的触发器供你选择,适用不同的调度需求。

你将会在第五课 Simple Triggers和第六课Cron Triggers学到两种常用的触发器类型。

4.1 通用的Trigger属性

所有类型的触发器都有TriggerKey属性去跟踪触发器标识,还有许多其他的属性,对所有触发器类型都适用。这些通用属性在创建触发器定义时通过TriggerBuilder类来设定的(下面会有例子)

下面的属性列表对所有类型的触发器都通用:

1、jobKey表示job实例的标识,触发器点火时,job实例会执行。

2、startTime表示触发器的时间表首次被触发的时间。它的值是 java.util.Date 对象,定义了给定日器的时刻。对于一些类型的触发器,会在启动时间触发,另一些触发器则仅仅是标示了调度器将要被触发的时间。这意味着你可以在调度器中存储一个触发器,例如每月的5号,如果现在是一月份,而startTime参数又设置为4月1日,那这样需要几个月后触发器才会第一次被触发。

3、endTime指定触发器的调度计划不再被触发的时间。换言之,调度器中的触发器定义为“每月的5号”,而且endTime设置为7月1日,那么6月5日将会是最后一次触发的日期。

其它的属性,更多更详细的讲解将会在接下来的子章节中进行讨论。

4.2 优先级

有些时候,当你有许多触发器(或Quartz线程池中只有少数几个工作线程),Quartz可能没有足够的资源去触发所有的在同一时间段内排定好的触发器。既然这样,你可能期望控制哪个触发器能第一个获得Quartz空闲工作线程的调用。为了达到这个目的,你可以设定触发器的Priority属性。如果N个触发器在同一时间内被触发,但只有Z工作线程当前空闲可用,那么拥有最高优先级的Z触发器将会第一个被触发。如果你没有设置触发器的优先级,它将会使用默认的优先级,优先级值为5任何Integer类型的值都可以作为优先级,正数负数都可以。

提示:优先级只是用于在同一时间被触发的触发器进行比较。一个安排在10:59分触发的触发器永远要比安排在11:00的触发器先执行。

提示:当一个触发器的作业任务发现设置了请求恢复参数,在恢复调度执行时的优先级和原来的一样。

4.3 触发失败指令

触发器另外一个重要的属性就是misfire instruction”。触发失败的情况是由于调度器被关闭导致存储的触发器错过了触发的时间,或是由于Quartz线程池内没有空闲的线程去执行作业任务。不同类型的触发器有不同的触发失败处理机制。默认情况下使用智能策略指令——基于触发器类型和配置的动态机制。当调度器启动时,它会查询所有存储的、触发失败的触发器,然后根据各自配置的触发失败指令更新触发器。当你开始在你的项目中使用Quartz时,你应该让自己熟悉在给定触发器类型上定义的触发失败指令和API上的文档解释。更多关于触发失败指令的详细信息将会在教程里每个触发器类型课程中作详细介绍。

4.4 Quartz Calendar对象

当在scheduler定义和存储触发器时,Quartz Calendar对象(不是java.util.Calendar对象可以与触发器相关联。Calendar于排除触发器调度不包含的时间段非常方便。例如,你可以创建一个触发器,定义在每个工作日上午9:30分触发作业任务,另外添加一个日历表排除当中所有的假期。

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

Calendar接口

package org.quartz;

public interface Calendar {

  public boolean isTimeIncluded(long timeStamp);

  public long getNextIncludedTime(long timeStamp);

}

注意,这些方法的参数类型都是long。正如你想的,它们都是以毫秒格式的时间戳。这意味着calendar对象能够排除的最窄时间段是1毫秒。你最可能排除的是整天。因此Quartz包含类org.quartz.impl.HolidayCalendar,就是干这个的。

Calendar实例化后,必须通过addCalendar方法注册到调度器中。如果你使用HolidayCalendar,初始化对象完成后,应该使用addExcludedDate(Datedate)方法将你希望从调度时间表中排除的日期添加到日历实例对象中。同一个日历实例对象可以应用于多个触发器,例如

Calendar示例

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实现类,估计有适合你需要的类


原创粉丝点击