与Job一样,Trigger也很容易使用,但是还有一些扩展选项需要理解,以便更好地使用Qartz。Trigger也有很多类型,我们可以根据实际需要来选择。
最常用的两种Trigger会分别在第五章:SimpleTrigger和第六章:CronTrigger中讲到。
所有类型的Trigger都有TriggerKey这个属性,表示Trigger的身份(唯一标识);除此之外,Trigger还有很多其它的公共属性。这些属性,在构建Trigger的时候可以通过TriggerBuilder设置。Trigger的公共属性有:
其它的属性,会在下文中解释。
有时候,当你有很多Trigger实例(或者你的Quartz线程池中只有有少量工作线程,不足以触发所有的触发器)时,Quartz可能没有足够的资源来立即触发所有计划同时触发的触发器。在这种情况下,你可能想要控制哪些Trigger可以优先使用(在当前可用的)Quartz工作线程。为此,你可以在触发器上设置优先级属性。如果N个触发器同时触发,但当前只有Z个工作线程可用,则首先执行具有最高优先级的Z个触发器。如果您没有在触发器上设置优先级,那么它将使用默认优先级5。priority属性的值可以是任意整数,正数或者负数都是允许的。
Trigger还有一个重要的属性misfire(这里应该称为“错过触发策略”更合理,本质就是一次处理触发器错失触发的策略);如果Scheduler关闭了,或者Quartz线程池中没有可用的线程来执行jJb,此时持久性的Trigger就会错过(miss)其触发时间,即错过触发(misfire)。不同类型的Trigger,有不同的misfire机制。它们默认都使用“智能机制(smart policy)”,即根据Trigger的类型和配置动态调整行为。当Scheduler启动的时候,查询所有错过触发(misfire)的持久化的Trigger。然后根据它们各自的misfire机制更新Trigger的信息。当你在项目中使用Quartz时,你应该对各种类型的Trigger的misfire机制都比较熟悉,这些misfire机制在JavaDoc中有说明。关于misfire机制的细节,会在讲到具体的Trigger时再作介绍。
Quartz的org.quartz.Calendar对象(不是java.util.Calendar对象)可以在定义和存储Trigger的时候与Trigger进行关联。Calendar用于从Trigger的调度计划中排除时间段。比如,可以创建一个Trigger,每个工作日的上午9:30执行,然后增加一个Calendar,排除掉所有的业务假期(也就是工作日中的法定假期)。
任何实现了Calendar接口的可序列化对象都可以作为Calendar对象,Calendar接口如下:
package org.quartz;
public interface Calendar {
public boolean isTimeIncluded(long timeStamp);
public long getNextIncludedTime(long timeStamp);
}
译者吐槽:这里贴出来的Calendar接口的源码估计是老版本的org.quartz.Calendar接口,对比了下2.2.x版本的同一个接口并不是长这样的。
注意到这些方法的参数类型为long。你也许猜到了,他们就是毫秒单位的时间戳。即Calendar排除时间段的单位可以精确到毫秒。你也许对“排除一整天”的Calendar比较感兴趣。Quartz提供的org.quartz.impl.HolidayCalendar类可以很方便地实现。
Calendar必须先实例化,然后通过addCalendar()
方法注册到Scheduler。如果使用HolidayCalendar,实例化后,需要调用addExcludedDate(Date date)
方法从调度计划中排除时间段。以下示例是将同一个Calendar实例用于多个Trigger:
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
接下来的几个章节将介绍触发器的构建/构建细节。现在,只要明确上面的代码会创建两个触发器,每个触发器都计划每天触发一次。但是,在日历(Calendar)排除的期间内发生的任何触发都将被跳过。
请参阅org.quartz.impl.calendar包,了解适合你的Calendar实现。
原文链接:tutorial-lesson-04
本文是Throwable的原创文章,转载请提前告知作者并且标明出处。 博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议 本文永久链接是:https://cloud.tencent.com/developer/article/1649916