第五课 SimpleTrigger
如果你需要在一个指定时间段内执行一次作业任务或是在指定的时间间隔内多次执行作业任务,SimpleTrigger应该能满足你的调度需求。例如,你希望触发器在2015年1月13日上午11:23:54准时触发,或是希望在那个时间点触发,然后再重复触发5次,每隔10秒一次。有了这样的描述,你就不会对SimpleTrigger包含的参数感到奇怪:开始执行时间,结束执行时间,重复次数和重复执行间隔时间。所有的参数都是你期望的那样,只是关于结束执行时间参数有两条特别的提示。
重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值。重复执行间隔必须为0或长整数(long类型),它表示毫秒数的值。注意如果重复执行间隔时间为0会导致数量为“重复次数”的触发器并发执行(或是在调度器控制下接近并发执行)。
如果你还不熟悉Quartz的DateBuilder类,你尝试创建日期对象时会发现它非常方便地根据startTimeUtc 或 endTimeUtc参数计算触发器的触发时间。
EndTimeUtc参数(如果被指定)会覆盖重复次数参数的效果。当你希望创建一个触发器,每隔10秒被触发一次直到给定的截止时间,而不是必须完成在给定的开始和结束时间段内的触发次数,使用endTime参数会非常方便,你可以仅仅指定一个end-time参数,并且将重复次数设置为REPEAT_INDEFINITELY(你甚至可以将重复次数指定为非常大的值,确保比结束执行时间到达前实际要执行的次数大就行)。
下面是使用简易调度器定义触发器的几个案例,请通读一遍,每个例子都至少展示了一个新的、不同的知识点:
创建触发器时指定具体的时间,不重复执行:
1 // trigger builder creates simple trigger by default, actually an ITrigger is returned 2 ISimpleTrigger trigger = (ISimpleTrigger) TriggerBuilder.Create() 3 .WithIdentity("trigger1", "group1") 4 .StartAt(myStartTime) // some Date 5 .ForJob("job1", "group1") // identify job with name, group strings 6 .Build();
创建触发器时指定具体的时间,然后每隔10秒触发一次,共重复触发10次:
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger3", "group1") 3 .StartAt(myTimeToStartFiring) // if a start time is not given (if this line were omitted), "now" is implied 4 .WithSimpleSchedule(x => x 5 .WithIntervalInSeconds(10) 6 .WithRepeatCount(10)) // note that 10 repeats will give a total of 11 firings 7 .ForJob(myJob) // identify job with handle to its JobDetail itself 8 .Build();
创建触发器,5分钟后将会触发一次:
trigger = (ISimpleTrigger) TriggerBuilder.Create() .WithIdentity("trigger5", "group1") .StartAt(DateBuilder.FutureDate(5, IntervalUnit.Minute)) // use DateBuilder to create a date in the future .ForJob(myJobKey) // identify job with its JobKey .Build();
创建触发器时立即触发,然后每隔5分钟触发一次,直到22:00:
trigger = TriggerBuilder.Create() .WithIdentity("trigger7", "group1") .WithSimpleSchedule(x => x .WithIntervalInMinutes(5) .RepeatForever()) .EndAt(DateBuilder.DateOf(22, 0, 0)) .Build();
创建触发器时,在下一个整点小时触发,然后每隔2小时触发一次,永不停歇:
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group 3 .StartAt(DateBuilder.EvenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00")) 4 .WithSimpleSchedule(x => x 5 .WithIntervalInHours(2) 6 .RepeatForever()) 7 // note that in this example, ‘forJob(..)‘ is not called 8 // - which is valid if the trigger is passed to the scheduler along with the job 9 .Build(); 10 11 scheduler.scheduleJob(trigger, job);
花点时间查阅TriggerBuilder和SimpleScheduleBuilder类的所有可用方法,以便你能熟悉在上面演示代码中可能没有展示的有用操作。
注意TriggerBuilder(或是Quartz别的创建类)在你没有明确设置参数值时一般会选择合理的值。例如,如果你没有调用withIdentity方法,TriggerBuilder会为你的触发器产生一个随机的名字,如果你没有调用startAt方法,它会假设是立即触发。
SimpleTrigger的触发失败指令
SimpleTrigger有几条指令,用来告知Quartz当触发失败时该如何操作。(在第四课更多关于触发器已经介绍过触发失败的情况)。这些指令在SimpleTrigger类中设计成常量(包含JavaDoc描述了它们的行为)。指令有:
SimpleTrigger的触发失败指令常量:
•MisfireInstruction.IgnoreMisfirePolicy
•MisfirePolicy.SimpleTrigger.FireNow
•MisfirePolicy.SimpleTrigger.RescheduleNowWithExistingRepeatCount
•MisfirePolicy.SimpleTrigger.RescheduleNowWithRemainingRepeatCount
•MisfirePolicy.SimpleTrigger.RescheduleNextWithRemainingCount
•MisfirePolicy.SimpleTrigger.RescheduleNextWithExistingCount
回顾前面的课程可以知道:所有的触发器都可以使用Trigger.MISFIRE_INSTRUCTION_SMART_POLICY指令,并且这条指令也是所有触发器的默认指令。
如果使用“智能策略”指令,SimpleTrigger会从多条触发失败指令集中根据配置和SimpleTrigger实例的状态动态地选择指令。文档中SimpleTrigger的SimpleTrigger.UpdateAfterMisfire()方法解释了动态选择行为更详细的信息。
当你创建SimpleTrigger时,可以通过SimpleSchedulerBuilder指定触发失败指令作为调度器的一部分。
1 trigger = TriggerBuilder.Create() 2 .WithIdentity("trigger7", "group1") 3 .WithSimpleSchedule(x => x 4 .WithIntervalInMinutes(5) 5 .RepeatForever() 6 .WithMisfireHandlingInstructionNextWithExistingCount()) 7 .Build();