五. Quartz 工具插件
Quartz 框架包括几个你能用于你的应用中的几个插件。本节简单描述它们和它们的用途。
·JobInitializationPlugin
我们已经多次谈到过这个插件。它从一个 XML 文件中加载 Job 和 Trigger 信息(默认文件名是 quartz_jobs.xml) 。你可以通过在 quartz.properties 文件中为这个插件设定 filename 参数来配置文件名。假如你不需要数据库来存储你的 Job 或者是需要能快速测试特定 Job 的话,这个插件非常有帮助。
·JobInitializationPluginMulitple
显然,由其相似的名字,JobInitializationPluginMultiple 类似于 JobInitializationPlugin。不同点在于它支持从多个 XML 文件加载而非只是一个。它也类似于代码 8.2 中的 JobLoaderPlugin,只是代码 8.2 的插件查找一个目录,而不是一系列的文件。
指定给 JobInitializationPluginMultiple 的文件是以逗分进行分隔,配置在 quartz.properties 文件中的。这个插件的一个最好的特征就是能定期的扫描是否有修改,当它们有改变时能重新加载 Job 信息。它是通过实现 org.quartz.jobs.FileScanListener 来加入这一行为的。扫描间隔(定义为秒) 可以在属性文件中指定。
·LogginJobHistoryPlugin
org.quartz.plugins.history.LogginJobHistoryPlugin 是用来记录 Job 历史的,应用的是 commons-logging 框架。这包括 Job 的执行还有任何 Job 被否决的日志。这个插件允许配置日志消息,但已提供了默认的消息格式。格式可以指定 Job 的哪些字段会包括在消息中。你能为下列事件提供分离的消息格式:
·jobFailedMessage 在 Job 执行失败时记录
·jobSuccessMessage 在 Job 完成执行时记录
·jobToBeFiredMessage 在 Job 即将执行时记录
·jobWasVetoedMessage 在 Job 要被否决时记录
例如,当你想要覆盖掉 Job 即将时的默认消息,并且你所关心,想在日志消息中看到的是 Job 的名称和执行时间,你可以加入以下行到 quartz.properties 文件:
org.quartz.plugin.jobHistory.class=org.quartz.plugins. history.LoggingJobHistoryPlugin
org.quartz.plugin.jobHistory.jobToBeFiredMessage=Job {0} is about to be fired at: {2, date, HH:mm:ss MM/dd/yyyy}
你可以在日志消息在包含多个有关 Job 的数据元素。表 8.1 列出了这些元素和它们的数据类型。
元素 | 数据类型 | 描述 |
0 | String | Job 的名称 |
1 | String | Job 组的名称 |
2 | Date | 当前日期 |
3 | String | Trigger 的名称 |
4 | String | Trigger 组的名称 |
5 | Date | 调度的触发时间 |
6 | Date | 调度的下一触发时间 |
7 | Integer | JobExecutionContext 的触发次数 |
每个事件能分开来配置在 quartz.properties 文件中。使用这个插件唯一负面是,假如你有许多的 Job,日志文件很快就被撑大,几乎就是过度的信息了。
·LoggingTriggerHistoryPlugin
这个插件相当于 Job 的历史插件,只是它用于 Trigger 的历史信息罢了。你可以为如下 Trigger 事件提供日志消息格式:
·triggerCompleteMessage 在 Trigger 完成了所有的触发再也不被触发时记录
·triggerFireMessage 在 Trigger 触发时记录
·triggerMisfiredMessage 在错过触发之后记录
就像是 LoggingJobHistoryPlugin,你可以在属性文件中覆盖掉默认的消息格式。
你可以在日志消息中包括有关 Trigger 的几个数据元素。表 8.2 列出了这些无素及数据类型。表 8.2 列出了能用于 Trigger 历史日志消息的元素。
元素 | 数据类型 | 描述 |
0 | String | Trigger 的名称 |
1 | String | Trigger 组的名称 |
2 | Date | 调度的触发时间 |
3 | Date | Trigger 下一次触发时间 |
4 | Date | Trigger 实际触发时间 |
5 | String | Job 的名称 |
6 | String | Job 组的名称 |
7 | Integer | JobExecutionContext 的触发次数 |
像是 LoggingJobHistoryPlugin 一样,这个插件也能记录大量的 ,特别是几个 Trigger 要经常触发。
·ShutdownHookPlugin
这个插件捕获 JVM 的关闭事件并强制关闭 Scheduler。你或许会说,“我为何需要在 JVM 已经在关闭时告诉 Scheduler 关闭自己呢?” 原因主要是让 Scheduler 能执行一个“干净”的关闭。
当这个插件的 initialize() 方法被调用时,它会加入一个新的 java.lang.Thread 到 JVM 中。在 JVM 获取到关闭事件后,这由两个事件之一所导致:
·当最后一个非守护线程退出或调用了 System.exit() 方法时的程序正常退出。
·JVM 响应用户输入后被终止,如用户按下了 Ctrl+C,或是系统范围的事件,像用户注销或系统关闭。
当 JVM 获取到关闭通知后,它对关闭线程执行一次回调并给这个线程以运行的机会。对 ShutdownHookPlugin 来说,run() 方法就会调用 Scheduler,并告诉它作出关闭操作。默认时,会传递一个布尔值 true 来调用 Scheduler 的 shutdown() 方法,这就等于告诉 Scheduler 执行一个“干净”的关闭。 这意味着 Scheduler 将要等待所有正在执行着的 Trigger 结束后才停止。
你可以告诉这个插件不去执行一个“干净”的关闭,那就要在 quartz.properties 文件中把这作为插件的参数。
[译者 Unmi 注:最后一句原文写得也有些含混不清,其实就是说要调用 Scheduler 的 shutdown() 方法时传递 false 参数的话,就要在 quartz.properties 中配置 ShutdownHookPlugin 的属性 cleanShutdown 为 false]
本文链接 https://yanbin.blog/quartz-job-scheduling-framework-8-5/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
为什么我的方法执行错误了,而Quartz仍然把JOB做掉了,并在数据库中删除了该JOB,请问该怎么解决呢?才能让错误的JOB再次执行。
不太明白具体的错误,请贴出详细的异常栈信息。
如果要添加ShutdownHookPlugin
是不是只要加quartz.properties裡加入
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true
可以了?
第八章第一部份裡有提到
SchedulerPlugin 的方法是在 Scheduler 的初始化和啟動期間被調用
應該不需要另外寫
而ShutdownHookPlugin也有實現SchedulerPlugin接口的方法了
是的。