监听 Scheduler 事件
org.quartz.SchedulerListener 接口包含了一系列的回调方法,它们会在 Scheduler 的生命周期中有关键事件发生时被调用。代码 9 列出了包括在 SchedulerListener 接口的方法。
代码 9. org.quartz.SchedulerListener 接口中的方法
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();
}
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();
}
正如你从代码 9 中列示看到的方法那样,SchedulerListener 是在 Scheduler 级别的事件产生时得到通知,不管是增加还是移除 Scheduler 中的 Job,或者是 Scheduler 遭遇到了严重的错误时。那些事件多是关于对 Scheduler 管理的,而不是专注于 Job 或 Trigger 的。
· jobScheduled() 和 jobUnscheduled() 方法
Scheduler 在有新的 JobDetail 部署或卸载时调用这两个中的相应方法。
· triggerFinalized() 方法
当一个 Trigger 来到了再也不会触发的状态时调用这个方法。除非这个 Job 已设置成了持久性,否则它就会从 Scheduler 中移除。
·triggersPaused() 方法
Scheduler 调用这个方法是发生在一个 Trigger 或 Trigger 组被暂停时。假如是 Trigger 组的话,triggerName 参数将为 null。
·triggersResumed() 方法
Scheduler 调用这个方法是发生成一个 Trigger 或 Trigger 组从暂停中恢复时。假如是 Trigger 组的话,triggerName 参数将为 null。
·jobsPaused() 方法
当一个或一组 JobDetail 暂停时调用这个方法。
·jobsResumed() 方法
当一个或一组 Job 从暂停上恢复时调用这个方法。假如是一个 Job 组,jobName 参数将为 null。
·schedulerError() 方法
在 Scheduler 的正常运行期间产生一个严重错误时调用这个方法。错误的类型会各式的,但是下面列举了一些错误例子:
·初始化 Job 类的问题
·试图去找到下一 Trigger 的问题
·JobStore 中重复的问题
·数据存储连接的问题
你可以使用 SchedulerException 的 getErrorCode() 或者 getUnderlyingException() 方法或获取到特定错误的更详尽的信息。
·schedulerShutdown() 方法
Scheduler 调用这个方法用来通知 SchedulerListener Scheduler 将要被关闭。
代码 10 展示了一个 SchedulerListener 实现
代码 10. 一个简单的 SchedulerListener 实现
package org.cavaness.quartzbook.chapter7;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
public class SimpleSchedulerListener implements SchedulerListener {
Log logger = LogFactory.getLog(SimpleSchedulerListener.class);
public void jobScheduled(Trigger trigger) {
String jobName = trigger.getJobName();
logger.info(jobName + " has been scheduled");
}
public void jobUnscheduled(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is being unscheduled");
} else {
logger.info(triggerName + " is being unscheduled");
}
}
public void triggerFinalized(Trigger trigger) {
String jobName = trigger.getJobName();
logger.info("Trigger is finished for " + jobName);
}
public void triggersPaused(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is being paused");
} else {
logger.info(triggerName + " is being paused");
}
}
public void triggersResumed(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is now resuming");
} else {
logger.info(triggerName + " is now resuming");
}
}
public void jobsPaused(String jobName, String jobGroup) {
if (jobName == null) {
// triggerGroup is being unscheduled
logger.info(jobGroup + " is pausing");
} else {
logger.info(jobName + " is pausing");
}
}
public void jobsResumed(String jobName, String jobGroup) {
if (jobName == null) {
// triggerGroup is being unscheduled
logger.info(jobGroup + " is now resuming");
} else {
logger.info(jobName + " is now resuming");
}
}
public void schedulerError(String msg, SchedulerException cause) {
logger.error(msg, cause.getUnderlyingException());
}
public void schedulerShutdown() {
logger.info("Scheduler is being shutdown");
}
}
package org.cavaness.quartzbook.chapter7;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.SchedulerException;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
public class SimpleSchedulerListener implements SchedulerListener {
Log logger = LogFactory.getLog(SimpleSchedulerListener.class);
public void jobScheduled(Trigger trigger) {
String jobName = trigger.getJobName();
logger.info(jobName + " has been scheduled");
}
public void jobUnscheduled(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is being unscheduled");
} else {
logger.info(triggerName + " is being unscheduled");
}
}
public void triggerFinalized(Trigger trigger) {
String jobName = trigger.getJobName();
logger.info("Trigger is finished for " + jobName);
}
public void triggersPaused(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is being paused");
} else {
logger.info(triggerName + " is being paused");
}
}
public void triggersResumed(String triggerName,
String triggerGroup) {
if (triggerName == null) {
// triggerGroup is being unscheduled
logger.info(triggerGroup + " is now resuming");
} else {
logger.info(triggerName + " is now resuming");
}
}
public void jobsPaused(String jobName, String jobGroup) {
if (jobName == null) {
// triggerGroup is being unscheduled
logger.info(jobGroup + " is pausing");
} else {
logger.info(jobName + " is pausing");
}
}
public void jobsResumed(String jobName, String jobGroup) {
if (jobName == null) {
// triggerGroup is being unscheduled
logger.info(jobGroup + " is now resuming");
} else {
logger.info(jobName + " is now resuming");
}
}
public void schedulerError(String msg, SchedulerException cause) {
logger.error(msg, cause.getUnderlyingException());
}
public void schedulerShutdown() {
logger.info("Scheduler is being shutdown");
}
}
和前面的例子一样,代码 10 中的 SimpleSchedulerListener 只提供了监听方法的简单实现。代码 11 使用了 SimpleSchedulerListener 类。
代码 11. 使用 SimpleSchedulerListener
>
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.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
public class Listing_7_11 {
static Log logger = LogFactory.getLog(Listing_7_11.class);
public static void main(String[] args) {
Listing_7_11 example = new Listing_7_11();
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();
// Create and register the scheduler listener
SchedulerListener schedulerListener =
new SimpleSchedulerListener();
scheduler.addSchedulerListener(schedulerListener);
// Start the scheduler
scheduler.start();
logger.info("Scheduler was started at " + new Date());
// Create the JobDetail
JobDetail jobDetail = new JobDetail("PrintInfoJob",
Scheduler.DEFAULT_GROUP, PrintInfoJob.class);
/*
* Set up a trigger to start firing now, with no end
* date/time, repeat forever and have 5 secs
* between each firing.
*/
Trigger trigger = TriggerUtils.makeSecondlyTrigger(5);
trigger.setName("SimpleTrigger");
trigger.setStartTime(new Date());
// Register the JobDetail and Trigger
scheduler.scheduleJob(jobDetail, trigger);
}
}
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.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
public class Listing_7_11 {
static Log logger = LogFactory.getLog(Listing_7_11.class);
public static void main(String[] args) {
Listing_7_11 example = new Listing_7_11();
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();
// Create and register the scheduler listener
SchedulerListener schedulerListener =
new SimpleSchedulerListener();
scheduler.addSchedulerListener(schedulerListener);
// Start the scheduler
scheduler.start();
logger.info("Scheduler was started at " + new Date());
// Create the JobDetail
JobDetail jobDetail = new JobDetail("PrintInfoJob",
Scheduler.DEFAULT_GROUP, PrintInfoJob.class);
/*
* Set up a trigger to start firing now, with no end
* date/time, repeat forever and have 5 secs
* between each firing.
*/
Trigger trigger = TriggerUtils.makeSecondlyTrigger(5);
trigger.setName("SimpleTrigger");
trigger.setStartTime(new Date());
// Register the JobDetail and Trigger
scheduler.scheduleJob(jobDetail, trigger);
}
}
相比于前面的例子,我们在代码 11 中作了些小许改动,来实际促使更多的 SchedulerListener 方法被调用。在代码 11 中,Scheduler 创建后是在 Job 注册之前被启动的。这就使得在 Job 部署时 jobScheduled() 方法能得到调用。我们也改变了 Trigger 只重复两次而不是无限的运行。这样能强制 triggerFinalized() 方法被调用,因为这个 Trigger 不再有机会触发了。除了这些人为的条件外,使用 SchedulerListener 就和使用 Job 或 Trigger 监听器是一样的了。