Quartz使用指南(四)-----触发器(Triggers)

4 触发器(Triggers)

与Job相比,Trigger相对来说比较简单容易,但是要能完全的掌握使用Quartz,使其包含各种自定义的时间表选项,我们必须先知道和理解Trigger。

4.1 日历(Calendars)

Quartz Calendar 对象(不是java.util.Calendar对象)能够与被注册进Scheduler的Trigger关联。Calendar对排除Trigger的时间段是很有用的,例如,我们可以创建一个在每个工作日上午9:30触发Job的Trigger,就在其中增加一个排除所有工作假期的Calendar。

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

package org.quartz;

  public interface Calendar {

    public boolean isTimeIncluded(long timeStamp);

    public long getNextIncludedTime(long timeStamp);

  }

该接口的参数都是long类型的,以毫秒为单位的timestamp;所以Calendar定义的时间可以准确到毫秒。很可能,我们需要排除一整天,为了方便,Quartz包含了实现该功能的类ori.quartz.impl.HolidayCalendar。

Calendar必须实例化并且通过addCalendar(…)方法注册到Scheduler中,如果使用HolidayCalendar,在实例化之后,我们需要使用方法addExcludedDate(Date date)排除我们计划日程中不需要的日期,一个Calendar实例可以用到不同的Trigger中,比如:

HolidayCalendar cal = new HolidayCalendar();

  cal.addExcludedDate( someDate );

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

  SimpleTrigger trigger = new SimpleTrigger("myTrigger",

                                            sched.DEFAULT_GROUP,

                                            new Date(),

                                            null,

SimpleTrigger.REPEAT_INDEFINITELY,

                                            60L * 1000L);

  trigger.setCalendarName("myHolidays");

  // .. schedule job with trigger

  SimpleTrigger trigger2 = new SimpleTrigger("myTrigger",

                                             sched.DEFAULT_GROUP,

                                             new Date(),

                                             null,

                                             5,

                                      5L * 24L * 60L * 60L * 1000L);

  trigger2.setCalendarName("myHolidays");

  // .. schedule job with trigger2

上面代码,我们创建了两个Trigger:一个是每1分钟执行触发一次,没有次数限制;另一个是每5天执行触发一次,共执行5次触发;然而,任何在Calendar中被排除的时间段的触发执行都将被取消。

4.2 过时触发指令(Misfire Instructions)

Trigger另一个重要的属性是“Misfire Instruction”。过时触发发生在持久Trigger失去了触发时间,由于对应的Scheduler被关闭的原因;不同的Trigger类型有不同的过时触发指令,默认情况下是使用“smart policy”指令,该指令根据Trigger类型和配置具有动态的行为。当scheduler启动时,它将搜索所有过时触发的持久Trigger,并同时根据它们各自所配置的过时触发指令进行更新;当我们在项目中要使用Quartz时,我们必须熟悉所要使用的Trigger类型的过时触发指示,在对应的JavaDOC中有对其进行说明。可以通过方法setMisfireInstruction(…)来设置Trigger的过时触发指示。

4.3 触发器的辅助类(TriggerUtils)

提供了方便,可以使我们不TriggerUtils类(在org.quartz.helpers包中)为我们创建Trigger和触发时间用java.util.Calendar对象。使用辅助类能够很容易地创建基于每分钟、小时、天、周和月等触发的触发器,也可以创建各种各样的日期――对设置触发器的启动时间很有用。

4.4 触发器的监听器(TriggerListeners)

Trigger能够像Job一样,可以把监听器注册到Trigger中,实现了接口TriggerListener的对象就可以接收到Trigger触发时的通知。

4.5 Simple触发器(SimpleTrigger)

当我们需要在规定的时间执行一次或在规定的时间段以一定的时间间隔重复触发执行Job时,SimpleTrigger就可以满足上述要求。

SimpleTrigger的属性有:开始时间、结束时间、重复次数和重复的时间间隔,重复次数属性的值可以为0、正整数、或常量SimpleTrigger.REPEAT_INDEFINITELY,重复的时间间隔属性值必须为0或长整型的正整数,以毫秒作为时间单位,当重复的时间间隔为0时,意味着与Trigger同时触发执行(或几乎与Scheduler开始时同时触发执行)。

如果有指定结束时间属性值,则结束时间属性优先于重复次数属性,这样的好处在于:当我们需要创建一个每间隔10秒钟触发一次直到指定的结束时间的Trigger,而无需去计算从开始到结束的所重复的次数,我们只需简单的指定结束时间和使用REPEAT_INDEFINITELY作为重复次数的属性值即可(我们也可以指定一个比在指定结束时间到达时实际执行次数大的重复次数)。

SimpleTrigger有几个不同的构造方法,我们只对下面这个进行分析:

public SimpleTrigger(String name, String group, Date startTime,                       Date endTime, int repeatCount, long repeatInterval)

SimpleTrigger例1――创建一个在当前之后10秒钟触发的,执行一次的Trigger

long startTime = System.currentTimeMillis() + 10000L;

  SimpleTrigger trigger = new SimpleTrigger("myTrigger",

                                            sched.DEFAULT_GROUP,

                                            new Date(startTime),

                                            null,

                                            0,

                                            0L);

SimpleTrigger例2――创建一个立即触发的,并每间隔60秒钟重复触发执行一次的Trigger

SimpleTrigger trigger = new SimpleTrigger("myTrigger",

                                            sched.DEFAULT_GROUP,

                                            new Date(),

                                            null,

                                      SimpleTrigger.REPEAT_INDEFINITELY,

                                            60L * 1000L);

SimpleTrigger例3――创建一个立即触发,每间隔10秒钟重复触发执行一次,开始时间为当前,结束时间为40秒钟后的Trigger

long endTime = System.currentTimeMillis() + 40000L;

  SimpleTrigger trigger = new SimpleTrigger("myTrigger",

                                            sched.DEFAULT_GROUP,

                                            new Date(),

                                            new Date(endTime),

                                      SimpleTrigger.REPEAT_INDEFINITELY,

                                            10L * 1000L);

SimpleTrigger例4――创建一个在2005年5月8日早上10:30触发的,每间隔30秒钟重复触发执行一次,并且重复执行5次(总共触发执行6次)的Trigger

java.util.Calendar cal = new java.util.GregorianCalendar(2005, cal.MAY, 8);

  cal.set(cal.HOUR, 10);

  cal.set(cal.MINUTE, 30);

  cal.set(cal.SECOND, 0);

  cal.set(cal.MILLISECOND, 0);

  Data startTime = cal.getTime()

  SimpleTrigger trigger = new SimpleTrigger("myTrigger",

                                            sched.DEFAULT_GROUP,

                                            startTime,

                                            null,

                                            5,

                                            30L * 1000L);

4.6 Simple触发器的过时触发指令(SimpleTrigger Misfire Instructions)

SimpleTrigger有几个用于当过时触发发生时向Quartz通知如何执行的指令,这些指令作为常量定义在SimpleTrigger类中,分别如下:

  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,该指令是所有Trigger的默认值。

如果使用“smart policy”,SimpleTrigger将会根据实例中的配置进行动态的选择过时触发指令,JavaDOC中的SimpleTrigger.updateAfterMisfire()方法详细解析了动态选择的内容。


猜你喜欢

转载自it586.iteye.com/blog/1701799