四. 监听 Trigger 事件
正如 JobListener, org.quartz.TriggerListener 接口也包含一系列给 Scheduler 调用的方法。然而,与 JobListener 有所不同的是, TriggerListener 接口还有关于 Trigger 实例生命周期的方法。代码 7.5 列出了 TriggerListener 接口的方法。
代码 7.5. org.quartz.TriggerListener 接口的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public interface TriggerListener { public String getName(); public void triggerFired(Trigger trigger, JobExecutionContext context); public boolean vetoJobExecution(Trigger trigger, JobExecutidonContext context); public void triggerMisfired(Trigger trigger); public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode); } |
·getName() 方法
和前面的 JobListener 一样,TriggerListner 接口的 getName() 返回一个字符串用以说明监听器的名称。对于非全局的 TriggerListener,在 addTriggerListener() 方法中给定的名称必须与监听器的 getName() 方法返回值相匹配。
·triggerFired() 方法
当与监听器相关联的 Trigger 被触发,Job 上的 execute() 方法将要被执行时,Scheduler 就调用这个方法。在全局 TriggerListener 情况下,这个方法为所有 Trigger 被调用。
·vetoJobExecution() 方法
在 Trigger 触发后,Job 将要被执行时由 Scheduler 调用这个方法。TriggerListener 给了一个选择去否决 Job 的执行。假如这个方法返回 true,这个 Job 将不会为此次 Trigger 触发而得到执行。
·triggerMisfired() 方法
Scheduler 调用这个方法是在 Trigger 错过触发时。如这个方法的 JavaDoc 所指出的,你应该关注此方法中持续时间长的逻辑:在出现许多错过触发的 Trigger 时,长逻辑会导致骨牌效应。你应当保持这上方法尽量的小。
·triggerComplete() 方法
Trigger 被触发并且完成了 Job 的执行时,Scheduler 调用这个方法。这不是说这个 Trigger 将不再触发了,而仅仅是当前 Trigger 的触发(并且紧接着的 Job 执行) 结束时。这个 Trigger 也许还要在将来触发多次的。
代码 7.6 展示了一个很简单的 TriggerListener 实现
代码 7.6. 一个简单的 TriggerListener 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package org.cavaness.quartzbook.chapter7; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.JobExecutionContext; import org.quartz.Trigger; import org.quartz.TriggerListener; public class SimpleTriggerListener implements TriggerListener { Log logger = LogFactory.getLog(SimpleTriggerListener.class); private String name; public SimpleTriggerListener(String name) { this.name = name; } public String getName() { return name; } public void triggerFired(Trigger trigger, JobExecutionContext context) { String triggerName = trigger.getName(); logger.info(triggerName + " was fired"); } public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) { String triggerName = trigger.getName(); logger.info(triggerName + " was not vetoed"); return false; } public void triggerMisfired(Trigger trigger) { String triggerName = trigger.getName(); logger.info(triggerName + " misfired"); } public void triggerComplete(Trigger trigger, JobExecutionContext context, int triggerInstructionCode) { String triggerName = trigger.getName(); logger.info(triggerName + " is complete"); } } |
正如代码7.2 中的 JobListener 一样,代码 7.6 中的 TriggerListener 也是初步的。 它不过是在 Scheduler 调用它的方法时打印了一条日志信息。代码 7.7 中代码测试了这个简单的 TriggerListener。
代码 7.7. 使用 SimpleTriggerListener 作为一个全局的 TriggerListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
package org.cavaness.quartzbook.chapter7; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cavaness.quartzbook.common.PrintInfoJob; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerListener; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_7_7 { static Log logger = LogFactory.getLog(Listing_7_7.class); public static void main(String[] args) { Listing_7_7 example = new Listing_7_7(); try { example.startScheduler(); } catch (SchedulerException ex) { logger.error(ex); } } public void startScheduler() throws SchedulerException { // Create an instance of the factory Scheduler scheduler = null; // Create the scheduler and JobDetail scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create and register the global job listener TriggerListener triggerListener = new SimpleTriggerListener("SimpleTriggerListener"); scheduler.addGlobalTriggerListener(triggerListener); /* * Set up a trigger to start firing now, with no end * date/time, repeat forever and have 10 secs * (10000 ms) between each firing. */ Trigger trigger = TriggerUtils.makeSecondlyTrigger(10); trigger.setName("SimpleTrigger"); trigger.setStartTime(new Date()); // Register the JobDetail and Trigger scheduler.scheduleJob(jobDetail, trigger); // Start the scheduler scheduler.start(); logger.info("Scheduler was started at " + new Date()); } } |
代码 7.7 显示了如何注册 SimpleTriggerListener 为一个全局的 TriggerListener。它看起来与代码 7.3 中用来注册一个全局 JobListener 的代码完全相似。你只需要调用 addGloabelTriggerListener() 方法并传入这个 TriggerListener 实例。
·注册为非全局的 TriggerListener
要注册为一个非全局的 TriggerListener,你必须调用 addTriggerListener() 方法并传入这个 TriggerListener 实例。接着调用 Trigger 实例的 addTriggerListener() 方法并传入这个 TriggerListener 的名称。
在代码 7.8 中展示了这一过程。
代码 7.8. 使用一个非全局的 TriggerListener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
package org.cavaness.quartzbook.chapter7; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cavaness.quartzbook.common.PrintInfoJob; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerListener; import org.quartz.TriggerUtils; import org.quartz.impl.StdSchedulerFactory; public class Listing_7_8 { static Log logger = LogFactory.getLog(Listing_7_8.class); public static void main(String[] args) { Listing_7_8 example = new Listing_7_8(); try { example.startScheduler(); } catch (SchedulerException ex) { logger.error(ex); } } public void startScheduler() throws SchedulerException { // Create an instance of the factory Scheduler scheduler = null; // Create the scheduler and JobDetail scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail jobDetail = new JobDetail("PrintInfoJob", Scheduler.DEFAULT_GROUP, PrintInfoJob.class); // Create and register the nonglobal job listener TriggerListener triggerListener = new SimpleTriggerListener("SimpleTriggerListener"); scheduler.addTriggerListener( triggerListener ); /* * Set up a trigger to start firing now, with no end * date/time, repeat forever and have 10 secs * (10000 ms) between each firing. */ Trigger trigger = TriggerUtils.makeSecondlyTrigger(10); trigger.setName("SimpleTrigger"); trigger.setStartTime(new Date()); // Set the listener name for the trigger trigger.addTriggerListener( triggerListener.getName() ); // Register the JobDetail and Trigger scheduler.scheduleJob(jobDetail, trigger); // Start the scheduler scheduler.start(); logger.info("Scheduler was started at " + new Date()); } } |
针对于前面的非全局 JobListener 提到的相同的警告可以应用到这里来;你必须在把它设置给 Trigger 实例并存储了 Trigger 之前把 TriggerListener 加入到 Scheduler 中。
本文链接 https://yanbin.blog/quartz-job-scheduling-framework-7-3/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。