Quartz Job Scheduling Framework[翻译]第七章. 实现 Quartz 监听器 (第二部分)

三. 监听 Job 事件

org.quartz.JobListener 接口包含一系列的方法,它们会由 Job 在其生命周期中产生的某些关键事件时被调用。JobListener 可用的方法显示在代码 7.1 中。

代码 7.1. org.quartz.JobListener 接口中的方法


JobListener 接口中的方法用途是十分明了的。然后,我们还是要对他们加以简单说明。

·getName() 方法

getName() 方法返回一个字符串用以说明 JobListener 的名称。对于注册为全局的监听器,getName() 主要用于记录日志,对于由特定 Job 引用的 JobListener,注册在 JobDetail 上的监听器名称必须匹配从监听器上 getName() 方法的返回值。在你看完一些例子之后就会很清楚了。

·jobToBeExecuted() 方法

Scheduler 在 JobDetail 将要被执行时调用这个方法。

·jobExecutionVetoed() 方法

Scheduler 在 JobDetail 即将被执行,但又被 TriggerListener 否决了时调用这个方法。

·jobWasExecuted() 方法

Scheduler 在 JobDetail 被执行之后调用这个方法。

代码 7.2 展示了一个很简单的 JobListener 实现。

代码 7.2. 一个简单的 JobListner 实现

代码 7.2 中的 JobListener 打印一个日志消息,很明显,只是监听器最基本的用法。你要实现的逻辑完全由你和你的应用需要而定。你也许想在 Job 成功完成后发送一个电子邮件,或者在 Job 被否决后部署另一个。你有在回调方法中执行几乎任何动作的自由。

前面,我们提到过 JobListener (和 TriggerListener) 能注册为全局或非全局的。注意了,我们并不需要事先知道在代码 7.2 中的 JobListener 是一个全局或是非全局的;我们仅仅是实现了接口和提供了监听器方法。代码 7.3 描绘了如何使用代码 7.2 中的 SimpleJobListner 使之注册为一个全局的 JobListener

代码 7.3. 使用 SimpleJobListener 作为一个全局 JobListener

代码 7.3 中的代码现在看来是相当直截的。创建了一个 JobDetail 和 Trigger 并注册到了 Scheduler 实例上,这在前面我们已是做过许多次了。

代码 7.2 中的 SimpleJobListener 初始化后通过 Scheduler 调用 addGlobalJobListener() 方法注册为一个全局的 JobListener。最后,启动 Scheduler。

因为我们只配置了单个 Job (PrintInfoJob),我们获得回调也只是那个 JobDetail。不过,假如我们部署了其他 Job,我们也能看到第二个 Job 的回调日志信息,因为这个监听顺是配置为全局的。

·注册非全局的 JobListener

你还能使用代码 7.2 中的 SimpleJobListener 作为一个非全局的 JobListener。要做到这点,你仅需要修改代码 7.3 的 startScheduler() 方法中的代码。代码 7.4 显示了这一需要做的小小的改变。

代码 7.4. 使用 SimpleJobListener 作为非全局的 JobListener

代码 7.4 很类似于代码 7.4 中的代码。因为 JobListener 是要注册为一个非全局的监听器,你就要调用 Scheduler 的 addJobListener() 方法而不是 addGlobalJobListener() 方法了。对于非全局的 JobListener,它应于任何引用到它的 JobDetail 使用 schedulerJob()addJob() 方法注册之前被注册。

接下来,JobListener 的名字要设置给 JobDetail。注意,设置的不是 JobListener 实例,仅仅是它的名称。这是通过调用 addJobListener() 方法并传入名称来完成的。传递给 addJobListener() 方法的名称必须匹配从监听器的 getName() 方法返回的名称。如果 Scheduler 不能根据名称找到监听器,它会抛出一个 SchedulerException 异常。

最后,启动 Scheduler。

非全局 JobListener 相关步骤的顺序加入一个非全局 JobListener 的步骤必须是依序完成。JobListener 必须首先加入到 Scheduler 中。接着,JobListener 才能够设置给 JobDetail 对象。之后,你就能使用 scheduleJob() 方法安全的把 JobDetail 加入到 Scheduler 中。

本文链接 https://yanbin.blog/quartz-job-scheduling-framework-7-2/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

4 Comments
Inline Feedbacks
View all comments
WaveFly
WaveFly
15 years ago

代码:
Listing_7_3 L52:

// Create and register the global job listener
JobListener jobListener =
new SimpleJobListener("SimpleJobListener");

上文中的SimpleJobListener类没有这个带参数的构造函数……

隔叶黄莺
15 years ago

是的,原文里也没有这个构造方法,这是它的一个纰漏。要你自己把这个方法补上,或者用 JobListener jobListener = new SimpleJobListener(); 来构造监听器实例。

LINQ
LINQ
15 years ago

重启后异常:org.quartz.SchedulerException: JobListener 'notifyJobListener' not found.
用JobStoreTX保存
代码:
JobListener notify = new NotifyJobListener();
if (scheduler.getJobListener(notify.getName()) == null) {
scheduler.addJobListener(notify);
}
jobDetail.addJobListener(notify.getName());
数据库保存了notify.getName()名字,没办法找到NotifyJobListener类

Kida
Kida
15 years ago

可否透过joblistener得知job未顺利执行完毕?

若有执行到jobToBeExecuted()而没执行到jobWasExecuted()

那表示job可能出错

但当下无法确定jobWasExecuted是还没执行到(job正在run)

还是已出错了!