Quartz手册java版.doc_第1页
Quartz手册java版.doc_第2页
Quartz手册java版.doc_第3页
Quartz手册java版.doc_第4页
Quartz手册java版.doc_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Quartz手册java版1.1 Quartz手册java版-(一)使用Quartz使用scheduler之前应首先实例化它。使用SchedulerFactory可以完成scheduler的实例化。用户可直接地实例化这个工厂类并且直接使用工厂的实例(例如下面的例子)。 一旦一个scheduler被实例化,它就可以被启动(start),并且处于驻留模式,直到被关闭(shutdown)。注意,一旦scheduler被关闭(shutdown),则它不能再重新启动,除非重新实例化它。除非scheduler 被启动或者不处于暂停状态,否则触发器不会被触发(任务也不能被执行)。 下面是一个代码片断,这个代码片断实例化并且启动了一个scheduler,接着将一个要执行的任务纳入了进程。SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();Scheduler sched = schedFact.getScheduler();sched.start();JobDetail jobDetail = new JobDetail(myJob, null, DumbJob.class);Trigger trigger = TriggerUtils.makeHourlyTrigger(); / fire every hourtrigger.setStartTime(TriggerUtils.getEvenHourDate(new Date(); / start on the next even hourtrigger.setName(myTrigger);sched.scheduleJob(jobDetail, trigger);如您所见,使用quartz相当简单,在第二课中,我们将给出一个Job和Trigger的快速预览,这样就能够充分理解这个例子。1.2 Quartz手册java版-(二)Jobs And Triggers正如前面所提到的那样,通过实现Job接口来使你的.NET组件可以很简单地被scheduler执行。下面是Job接口:package org.quartz;public interface Job public void execute(JobExecutionContext context) throws JobExecutionException;这样,你会猜想出,当Job触发器触发时(在某个时刻),Execute (.)就被scheduler所调用。JobExecutionContext对象被传递给这个方法,它为Job实例提供了它的“运行时”环境-一个指向执行这个IJob实例的Scheduler句柄,一个指向触发该次执行的触发器的句柄,IJob的JobDetail对象以及一些其他的条目。JobDetail对象由Quartz客户端在Job被加入到scheduler时创建。它包含了Job的各种设置属性以及一个JobDataMap对象,这个对象被用来存储给定Job类实例的状态信息。Trigger对象被用来触发jobs的执行。你希望将任务纳入到进度,要实例化一个Trigger并且“调整”它的属性以满足你想要的进度安排。Triggers也有一个JobDataMap与之关联,这非常有利于向触发器所触发的Job传递参数。Quartz打包了很多不同类型的Trigger,但最常用的Trigge类是SimpleTrigger和CronTrigger。SimpleTrigger用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。CronTrigger按照日历触发,例如“每个周五”,每个月10日中午或者10:15分。 为什么要分为Jobs和Triggers?很多任务日程管理器没有将Jobs和Triggers进行区分。一些产品中只是将“job”简单地定义为一个带有一些小任务标识的执行时间。其他产品则更像Quartz中job和trigger的联合。而开发Quartz的时候,我们决定对日程和按照日程执行的工作进行分离。(从我们的观点来看)这有很多好处。 例如:jobs可以被创建并且存储在job scheduler中,而不依赖于trigger,而且,很多triggers可以关联一个job.另外的好处就是这种“松耦合”能使与日程中的Job相关的trigger过期后重新配置这些Job,这样以后就能够重新将这些Job纳入日程而不必重新定义它们。这样就可以更改或者替换trigger而不必重新定义与之相连的job标识符。当向Quartz scheduler中注册Jobs 和Triggers时,它们要给出标识它们的名字。Jobs 和Triggers也可以被放入“组”中。“组”对于后续维护过程中,分类管理Jobs和Triggers非常有用。Jobs和Triggers的名字在组中必须唯一,换句话说,Jobs和Triggers真实名字是它的名字+组。如果使Job或者Trigger的组为null,这等价于将其放入缺省的Scheduler.DEFAULT_GROUP组中。1.3 Quartz手册java版-(三)更多关于Jobs和JobDetails如你所见,Job相当容易实现。这里只是介绍有关Jobs本质, Job接口的Execute(.)方法以及JobDetails中需要理解的内容。在所实现的类成为真正的“Job”时,期望任务所具有的各种属性需要通知给Quartz。通过JobDetail类可以完成这个工作,这个类在前面的章节中曾简短提及过。现在,我们花一些时间来讨论Quartz中Jobs的本质和Job实例的生命周期。首先让我们回顾一下第一课中所看到的代码片断JobDetail jobDetail = new JobDetail(myJob, / job name sched.DEFAULT_GROUP, / job group (you can also specify null to use the default group) DumbJob.class); / the java class to executeTrigger trigger = TriggerUtils.makeDailyTrigger(8, 30);trigger.setStartTime(new Date();trigger.setName(myTrigger);sched.scheduleJob(jobDetail, trigger);现在定义一个DumbJob类public class DumbJob implements Job public DumbJob() public void execute(JobExecutionContext context) throws JobExecutionException System.err.println(DumbJob is executing.); 注意我们传递给scheduler一个JobDetail实例,JobDetail关联一个job,提供job的class,每次scheduler执行job时,在执行execute(.)这前会创建一个实例.job必须有一个无参构造方法.你可能想问如何提供配置 job实例.或者保存job状态在执行过程中.答案是JobDataMap.它是JobDetail的一部分.JobDataMap JobDataMap被用来保存一系列的(序列化的)对象,这些对象在Job执行时可以得到。JobDataMap是Map接口的一个实现,而且还增加了一些存储和读取主类型数据的便捷方法。jobDetail.getJobDataMap().put(jobSays, Hello World!);jobDetail.getJobDataMap().put(myFloatValue, 3.141f);jobDetail.getJobDataMap().put(myStateData, new ArrayList();下面的代码展示了在Job执行过程中从JobDataMap 获取数据的代码public class DumbJob implements Job public DumbJob() public void execute(JobExecutionContext context) throws JobExecutionException String instName = context.getJobDetail().getName(); String instGroup = context.getJobDetail().getGroup(); JobDataMap dataMap = context.getJobDetail().getJobDataMap(); String jobSays = dataMap.getString(jobSays); float myFloatValue = dataMap.getFloat(myFloatValue); ArrayList state = (ArrayList)dataMap.get(myStateData); state.add(new Date(); System.err.println(Instance + instName + of DumbJob says: + jobSays); 如果使用一个持久的JobStore(在本指南的JobStore章节中讨论),那么必须注意存放在JobDataMap中的内容。因为放入JobDataMap中的内容将被序列化,而且容易出现类型转换问题。很明显,标准.NET类型将是非常安全的,但除此之外的类型,任何时候,只要有人改变了你要序列化其实例的类的定义,就要注意是否打破了程序的兼容性。另外,你可以对JobStore和JobDataMap采用一种使用模式:就是只把主类型和String类型存放在Map中,这样就可以减少后面序列化的问题。Triggers也可以有JobDataMaps与之相关联。当scheduler中的Job被多个有规律或者重复触发的Triggers所使用时非常有用。对于每次独立的触发,你可为Job提供不同的输入数据。 从Job执行时的JobExecutionContext中取得JobDataMap是惯用手段,它融合了从JobDetail和从Trigger中获的JobDataMap,当有相同名字的键时,它用后者的值覆盖前者值。下面给一个例子取数据从JobExecutionContext 关联JobDatMap在job执行中public class DumbJob implements Job public DumbJob() public void execute(JobExecutionContext context) throws JobExecutionException String instName = context.getJobDetail().getName(); String instGroup = context.getJobDetail().getGroup(); JobDataMap dataMap = context.getMergedJobDataMap(); / Note the difference from the previous example String jobSays = dataMap.getString(jobSays); float myFloatValue = dataMap.getFloat(myFloatValue); ArrayList state = (ArrayList)dataMap.get(myStateData); state.add(new Date(); System.err.println(Instance + instName + of DumbJob says: + jobSays); StatefulJob有状态任务 现在,一些关于Job状态数据的附加论题:一个Job实例可以被定义为“有状态的”或者“无状态的”。“无状态的”任务只拥有它们被加入到scheduler时所存储的JobDataMap。这意味着,在执行任务过程中任何对Job Data Map所作的更改都将丢失而且任务下次执行时也无法看到。你可能会猜想出,有状态的任务恰好相反,它在任务的每次执行之后重新存储JobDataMap。有状态任务的一个副作用就是它不能并发执行。换句话说,如果任务有状态,那么当触发器在这个任务已经在执行的时候试图触发它,这个触发器就会被阻塞(等待),直到前面的执行完成。 想使任务有状态,它就要实现StatefulJob 接口而不是实现Job接口.Job Instances 任务“实例” 这个课程的最终观点或许已经很明确,可以创建一个单独的Job类,并且通过创建多个JobDetails实例来将它的多个实例存储在scheduler中,这样每个JobDetails对象都有它自己的一套属性和JobDataMap,而且将它们都加入到scheduler中。当触发器被触发的时候,通过Scheduler中配置的JobFactory来实例化与之关联的Job类。缺省的JobFactory只是简单地对Job类调用newInstance()方法。创建自己JobFactory可以利用应用中诸如Ioc或者DI容器所产生或者初始化的Job实例。jobs的其它属性 这里简短地总结一下通过JobDetail对象可以定义Job的其它属性。 Durability(持久性)-如果一个Job是不持久的, 一旦没有触发器与之关联,它就会被从scheduler 中自动删除。 Volatility(无常性)-如果一个Job是无常的,在重新启动Quartz i scheduler 时它不能被保持。 RequestsRecovery(请求恢复能力) -如果一个Job具备“请求恢复”能力,当它在执行时遇到scheduler “硬性的关闭” (例如:执行的过程崩溃,或者计算机被关机),那么当scheduler重新启动时,这个任务会被重新执行。 这种情况下,JobExecutionContext.isRecovering() 属性将是true。 JobListeners(任务监听器) -一个Job如果有0个或者多个JobListeners监听器与之相关联,当这个Job执行时,监听器被会被通知。 更多有关JobListeners的讨论见TriggerListeners & JobListeners章节。JobExecutionException 任务执行异常 最后,需要告诉你一些关于Job.Execute(.)方法的细节。在Execute方法被执行时,仅允许抛出一个JobExecutionException类型异常。因此需要将整个要执行的内容包括在一个try-catch块中。应花费一些时间仔细阅读JobExecutionException文档,因为Job能够使用它向scheduler提供各种指示,你也可以知道怎么处理异常。1.4 Quartz手册java版-(四)关于Triggers更多内容同Job一样,trigger非常容易使用,但它有一些可选项需要注意和理解,同时,trigger有不同的类型,要按照需求进行选择。 Calendars日历 Quartz Calendar对象在trigger被存储到scheduler时与trigger相关联。Calendar对于在trigger触发日程中的采用批量世间非常有用。例如:你想要创建一个在每个工作日上午9:30触发一个触发器,那么就添加一个排除所有节假日的日历。 Calendar可以是任何实现Calendar接口的序列化对象。看起来如下; package org.quartz;public interface Calendar public boolean isTimeIncluded(long timeStamp);public long getNextIncludedTime(long timeStamp);注意,这些方法的参数都是DateTime型,你可以猜想出,它们的时间戳是毫秒的格式。这意味日历能够排除毫秒精度的时间。最可能的是,你可能对排除整天的时间感兴趣。为了提供方便,Quartz提供了一个Quartz.Impl.Calendar.HolidayCalendar,这个类可以排除整天的时间。Calendars必须被实例化,然后通过addCalendar (.)方法注册到scheduler中。如果使用HolidayCalendar,在实例化之后,你可以使用它的AddExcludedDate (DateTime excludedDate)方法来定义你想要从日程表中排除的时间。同一个calendar实例可以被用于多个trigger中,如下:HolidayCalendar cal = new HolidayCalendar();cal.addExcludedDate( someDate );sched.addCalendar(myHolidays, cal, false);Trigger trigger = TriggerUtils.makeHourlyTrigger(); / fire every one hour intervaltrigger.setStartTime(TriggerUtils.getEvenHourDate(new Date(); / start on the next even hourtrigger.setName(myTrigger1);trigger.setCalendarName(myHolidays);/ . schedule job with triggerTrigger trigger2 = TriggerUtils.makeDailyTrigger(8, 0); / fire every day at 08:00trigger.setStartTime(new Date(); / begin immediatelytrigger2.setName(myTrigger2);trigger2.setCalendarName(myHolidays);/ . schedule job with trigger2传入SimpleTrigger构造函数的参数的细节将在下章中介绍。但是,任何在日历中被排除的时间所要进行的触发都被取消。Priority有时,当有多个Triggers时,Quartz没有足够的资源来同时立即处理scheduled的trigger.所以你可能要控制哪个先执行.在这种情况下,你要设置Trigger的priority,如果N个triggers不会同时触发.但此时只有有限的几个线程可用.这时会先处理级别高的trigger.如果你没有设置级别,默认为5,下面为一个例子:Calendar cal = Calendar.getInstance();cal.add(Calendar.MINUTE, 5);Trigger trig1 = new SimpleTrigger(T1, MyGroup, cal.getTime();Trigger trig2 = new SimpleTrigger(T2, MyGroup, cal.getTime();Trigger trig3 = new SimpleTrigger(T3, MyGroup, cal.getTime();JobDetail jobDetail = new JobDetail(MyJob, MyGroup, NoOpJob.class);/ Trigger1 does not have its priority set, so it defaults to 5sched.scheduleJob(jobDetail, trig1);/ Trigger2 has its priority set to 10trig2.setJobName(jobDetail.getName();trig2.setPriority(10);sched.scheduleJob(trig2);/ Trigger2 has its priority set to 1trig3.setJobName(jobDetail.getName();trig2.setPriority(1);sched.scheduleJob(trig3);/ Five minutes from now, when the scheduler invokes these three triggers/ they will be allocated worker threads in decreasing order of their/ priority: Trigger2(10), Trigger1(5), Trigger3(1)Misfire Instructions未触发指令 Trigger的另一个重要属性就是它的“misfire instruction(未触发指令)”。如果因为scheduler被关闭而导致持久的触发器“错过”了触发时间,这时,未触发就发生了。不同类型的触发器有不同的未触发指令。缺省情况下,他们会使用一个“智能策略”指令根据触发器类型和配置的不同产生不同动作。当scheduler开始时,它查找所有未触发的持久triggers,然后按照每个触发器所配置的未触发指令来更新它们。开始工程中使用Quartz的时,应熟悉定义在各个类型触发器上的未触发指令。关于未触发指令信息的详细说明将在每种特定的类型触发器的指南课程中给出。可以通过MisfireInstruction属性来为给定的触发器实例配置未触发指令。TriggerUtils - Triggers Made Easy(TriggerUtils使Triggers变得容易) TriggerUtils类包含了创建触发器以及日期的便捷方法。使用这个类可以轻松地使触发器在每分钟,小时,日,星期,月等触发。使用这个类也可以产生距离触发最近的妙、分或者小时,这对设定触发开始时间非常有用。TriggerListeners 最后,如同job一样,triggers可以注册监听器,实现TriggerListener接口的对象将可以收到触发器被触发的通知。1.5 Quartz手册java版-(五) SimpleTrigger如果需要让任务只在某个时刻执行一次,或者,在某个时刻开始,然后按照某个时间间隔重复执行,简单地说,如果你想让触发器在20XX年8月20日上午11:23:54秒执行,然后每个隔10秒钟重复执行一次,并且这样重复5次。那么SimpleTrigger 就可以满足你的要求。通过这样的描述,你可能很惊奇地发现SimpleTrigger包括这些属性:开始时间,结束时间,重复次数,重复间隔。所有这属性都是你期望它所应具备的,只有end-time属性有一些条目与之关联。重复次数可能是0,正数或者一个常量值SimpleTrigger.REPEAT_INDEFINITELY。重复间隔时间属性可能是0,正的long型,这个数字以毫秒为单位。注意:如果指定的重复间隔时间是0,那么会导致触发器按照重复数量定义的次数并发触发(或者接近并发)。 org.quartz.helpers.TriggerUtils 类对处理这样的循环也提供了很多支持。endTime(如果这个属性被设置)属性会覆盖重复次数属性,这对创建一个每隔10秒就触发一次直到某个时间结束的触发器非常有用,这就可以不计算开始时间和结束时间之间的重复数量。也可以指定一个结束时间,然后使用REPEAT_INDEFINITELY作为重复数量。(甚至可以指定一个大于结束时间之前实际重复次数的整数作为重复次数)。一句话,endTime属性控制权高于重复次数属性。SimpleTrigger有几个不同的构造函数,下面我们来看看这结果构造函数:public SimpleTrigger(String name, String group,Date startTime,Date endTime,int repeatCount,long repeatInterval)SimpleTrigger Example 1 - Create a trigger that fires exactly once, ten seconds from nowlong startTime = System.currentTimeMillis() + 10000L;SimpleTrigger trigger = new SimpleTrigger(myTrigger, null,new Date(startTime),null,0,0L);SimpleTrigger Example 2 - Create a trigger that fires immediately, then repeats every 60 seconds, foreverSimpleTrigger trigger = new SimpleTrigger(myTrigger, null, new Date(),null,SimpleTrigger.REPEAT_INDEFINITELY,60L * 1000L);SimpleTrigger Example 3 - Create a trigger that fires immediately, then repeats every 10 seconds until 40 seconds from nowlong endTime = System.currentTimeMillis() + 40000L;SimpleTrigger trigger = new SimpleTrigger(myTrigger,myGroup, new Date(),new Date(endTime), SimpleTrigger.REPEAT_INDEFINITELY,10L * 1000L);SimpleTrigger Example 4 - Create a trigger that fires on March 17 of the year 20XX at precisely 10:30 am, and repeats 5 times (for a total of 6 firings) - with a 30 second delay between each firingjava.util.Calendar cal = new java.util.GregorianCalendar(20XX, cal.MARCH, 17);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, null, startTime,null,5,30L * 1000L);SimpleTrigger Misfire InstructionsSimpleTrigger的未触发指令 “未触发”发生时,SimpleTrigger有几个指令可以用来通知Quartz进行相关处理。(“未触发”在上节课中介绍过了)。这些指令以常量形式定义在SimpleTrigger本身,这些指令如下:MISFIRE_INSTRUCTION_FIRE_NOWMISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNTMISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNTMISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNTMISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT回顾前面的课程你可以知道,每个触发器都有一个Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令可用,并且,这个指令对于每个类型的触发器都是缺省的。如果使用 smart policy 指令,SimpleTriger会基于配置和SimpleTrigger实例的状态动态的选择上面的指令.SimpleTrigger.updateAfterMisfire() 会获取动态行为的详细信息.1.6 Quartz手册java版-(六)CronTrigger如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger 那样每隔特定的间隔时间触发,CronTriggers通常比SimpleTrigger更有用。使用CronTrigger,你可以指定诸如“每个周五中午”,或者“每个工作日的9:30”或者“从每个周一、周三、周五的上午9:00到上午10:00之间每隔五分钟”这样日程安排来触发。甚至,象SimpleTrigger一样,CronTrigger也有一个StartTime以指定日程从什么时候开始,也有一个(可选的)EndTime以指定何时日程不再继续。Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串。每个子表达式都描述了一个单独的日程细节。这些子表达式用空格分隔,分别表示: 1. Seconds 秒 2. Minutes 分钟 3. Hours 小时 4. Day-of-Month 月中的天 5. Month 月 6. Day-of-Week 周中的天 7. Year (optional field) 年(可选的域) 一个cron表达式的例子字符串为0 0 12 ? * WED,这表示“每周三的中午12:00”。单个子表达式可以包含范围或者列表。例如:前面例子中的周中的天这个域(这里是WED)可以被替换为MON-FRI, MON, WED, FRI或者甚至MON-WED,SAT。 通配符(*)可以被用来表示域中“每个”可能的值。因此在Month域中的*表示每个月,而在Day-Of-Week域中的*则表示“周中的每一天”。 所有的域中的值都有特定的合法范围,这些值的合法范围相当明显,例如:秒和分域的合法值为0到59,小时的合法范围是0到23,Day-of-Month中值得合法凡范围是0到31,但是需要注意不同的月份中的天数不同。月份的合法值是0到11。或者用字符串JAN,FEB MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV 及DEC来表示。Days-of-Week可以用1到7来表示(1=星期日)或者用字符串SUN, MON, TUE, WED, THU, FRI 和SAT来表示./字符用来表示值的增量,例如, 如果分钟域中放入0/15,它表示“每隔15分钟,从0开始”,如果在份中域中使用3/20,则表示“小时中每隔20分钟,从第3分钟开始”或者另外相同的形式就是3,23,43。?字符可以用在day-of-month及day-of-week域中,它用来表示“没有指定值”。这对于需要指定一个或者两个域的值而不需要对其他域进行设置来说相当有用。L字符可以在day-of-month及day-of-week中使用,这个字符是last的简写,但是在两个域中的意义不同。例如,在day-of-month域中的L表示这个月的最后一天,即,一月的31日,非闰年的二月的28日。如果它用在day-of-week中,则表示7或者SAT。但是如果在day-of-week域中,这个字符跟在别的值后面,则表示当月的最后的周XXX。例如:6L 或者 FRIL都表示本月的最后一个周五。当使用L选项时,最重要的是不要指定列表或者值范围,否则会导致混乱。W 字符用来指定距离给定日最接近的周几(在day-of-week域中指定)。例如:如果你为day-of-month域指定为15W,则表示“距离月中15号最近的周几”。#表示表示月中的第几个周几。例如:day-of-week域中的6#3 或者 FRI#3表示“月中第三个周五”。例1 一个简单的每隔5分钟触发一次的表达式 0 0/5 * * * ? CronTrigger例2 在每分钟的10秒后每隔5分钟触发一次的表达式(例如. 10:00:10 am, 10:05:10等.)。 10 0/5 * * * ? CronTrigger 例3 在每个周三和周五的10:30,11:30,12:30触发的表达式。 0 30 10-13 ? * WED,FRI CronTrigger 例4 在每个月的5号,20号的8点和10点之间每隔半个小时触发一次且不包括10点,只是8:30,9:00和9:30的表达式。 0 0/30 8-9 5,20 * ? 注意,对于单独触发器来说,有些日程需求可能过于复杂而不能用表达式表述, 例如:9:00到10:00之间每隔5分钟触发一次,下午1:00到10点每隔20分钟触发一次。这个解决方案就是创建两个触发器,两个触发器都运行相同的任务。1.7 Quartz手册java版-(七)TriggerListeners和JobListeners监听器是在scheduler事件发生时能够执行动作的对象。可以看出,TriggerListeners接收与triggers相关的事件,而JobListeners则接收与Job相关的事件。Trigger相关的事件包括:trigger触发、trigger未触发,以及trigger完成(由trigger触发的任务被完成)。public interface TriggerListener public String getName(); public void triggerFired(Trigger trigger, JobExecutionContext context); public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context); public void triggerMisfired(Trigger trigger); public void triggerplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode);任务相关的事件包括:即将被执行的任务的通知和任务已经执行完毕的通知。public interface JobListener public String getName(); public void jobToBeExecuted(JobExecutionContext context); public void jobExecutionVetoed(JobExecutionContext context); public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException);使用你自定义的监听器创建监听器很简单,创建一个实现org.quartz.TriggerListener and/or org.quartz.JobListener 的接口。监听器然后在执行的时候注册到scheduler中,而且必须给定一个名字(或者,它们必须通过他们的Name属性来介绍自己)。监听器可以被注册为“全局”的或者“非全局”。“全局”监听器接收所有triggers/jobs产生的事件,而“非全局”监听器只接受那些通过getTriggerListenerNames() 或 getJobListenerNames()方法显式指定监听器名的triggers/jobs所产生的事件。正如上面所说的那样,监听器在运行时向scheduler注册,并且不被存储在jobs 和triggers的JobStore中。Jobs和Trigger只存储了与他们相关的监听器的名字。因此,每次应用运行的时候,都需要向scheduler重新注册监听器。scheduler.addGlobalJobListener(myJobListener);orscheduler.addJobListener(myJobListener);Quartz的大多数用户不使用监听器,但是当应用需要创建事件通知而Job本身不能显式通知应用,则使用监听器非常方便。1.8 Quartz手册java版-(八)SchedulerListenersSchedulerListeners同TriggerListeners及JobListeners非常相似,SchedulerListeners只接收与特定trigger 或job无关的Scheduler自身事件通知。 Scheduler相关的事件包括:增加job或者trigger,移除Job或者trigger, scheduler内部发生的错误,scheduler将被关闭的通知,以及其他。public interface SchedulerListener public void jobScheduled(Trigger trigger); public void jobUnscheduled(String triggerName, String triggerGroup); public void triggerFinalized(Trigger trigger); public void triggersPaused(String triggerName, String triggerGroup); public void triggersResumed(String triggerName, String triggerGroup); public void jobsPaused(String jobName, String jobGroup); public void jobsResumed(String jobName, String jobGroup); public void schedulerError(String msg, SchedulerException cause); public void schedulerShutdown();除了不分“全局”或者“非全局”监听器外,SchedulerListeners创建及注册的方法同其他监听器类型十分相同。所有实现Quartz.ISchedulerListener接口的对象都是SchedulerListeners。1.9 Quartz手册java版-(九)JobStoresJobStore负责保持对所有scheduler “工作数据”追踪,这些工作数据包括:job(任务),trigger(触发器),calendar(日历)等。为你的Quartz scheduler选择合适的JobStore是非常重要的一步,幸运的是,如果你理解了不同的JobStore之间的差别,那么选择就变得非常简单。在提供产生scheduler 实例的SchedulerFactory的属性文件中声明scheduler所使用的JobStore(以及它的配置)。 注:不要在代码中直接使用JobStore实例,处于某些原因,很多人试图这么做。JobStore是由Quartz自身在幕后使用。你必须告诉

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论