四. 使用多个插件
你喜欢多少个,就可以在 quartz.properties 文件中注册多少个插件。然而,加载和初始化的顺序却不能保证,因为 Quartz 加载先把所有的属性到一个 Map 中,然后按照从 Map 中取出的顺序遍历插件。
为规避这一限制,你可以创建一个 Quartz 插件作为父插件,然后以给定的顺序加载其他多个插件。代码 8.6 显示了 ParentPlugin 长什么样子。
代码 8.6. ParentPlugin 能以特定的顺序加载子插件
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
package org.cavaness.quartzbook.chapter8; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.quartz.Scheduler; import org.quartz.SchedulerConfigException; import org.quartz.SchedulerException; import org.quartz.spi.SchedulerPlugin; public class ParentPlugin implements SchedulerPlugin { private static Log logger = LogFactory.getLog(ParentPlugin.class); // A list of child plug-ins private List childPlugins = new ArrayList(); private String childPluginNames; private String pluginName; private Scheduler scheduler; /** * Default no-arg Constructor * */ public ParentPlugin() { } /** * Pass the initialize call on to the child plug-ins. * * @throws SchedulerConfigException * if there is an error initializing. */ public void initialize(String name, final Scheduler scheduler) throws SchedulerException { this.pluginName = name; this.scheduler = scheduler; logger.info("Searching for child plugins to load"); // The child plug-ins are comma-separated StringTokenizer tokenizer = new StringTokenizer(childPluginNames, ","); while (tokenizer.hasMoreElements()) { String pluginClassname = tokenizer.nextToken(); try { Class pluginClass = Class.forName(pluginClassname); Object obj = pluginClass.newInstance(); // Make sure the specified class is a plug-in if (obj instanceof SchedulerPlugin) { // Initialize the Plugin SchedulerPlugin childPlugin = (SchedulerPlugin) obj; logger.info("Init child Plugin " + pluginClassname); childPlugin.initialize(pluginClassname, scheduler); // Store the child plug-in in the list childPlugins.add(childPlugin); } else { // Skip loading class logger.error("Class is not a plugin " + pluginClass); } } catch (Exception ex) { // On error, log and go to next child plug-in logger.error("Error loading plugin " + pluginClassname, ex); } } } public void start() { // Start each child plug-in int size = childPlugins.size(); for (int i = 0; i < size; i++) { SchedulerPlugin childPlugin = ((SchedulerPlugin) childPlugins.get(i)); logger.info("Starting Child Plugin " + childPlugin); childPlugin.start(); } } public void shutdown() { // Stop each child plug-in int size = childPlugins.size(); for (int i = 0; i < size; i++) { SchedulerPlugin childPlugin = ((SchedulerPlugin) childPlugins.get(i)); logger.info("Stopping Plugin " + childPlugin); childPlugin.shutdown(); } } public String getPluginName() { return pluginName; } public void setPluginName(String pluginName) { this.pluginName = pluginName; } public String getChildPluginNames() { return childPluginNames; } public void setChildPluginNames(String childPluginNames) { this.childPluginNames = childPluginNames; } } |
代码 8.6 中的插件基什么也不做,也就只能算作一个插件,但是它扮演着子插件的加载器。一个子插件是个有效的 Quartz 插件,它可以是你所编写的或者是包含在框架中的。
·配置文件 quartz.properties 中的 ParentPlugin
要配置 quartz.properties 文件中的 ParentPlugin,仅要加入作为其他插件的父类。那就是,添加如下的行:
org.quartz.plugin.parentPlugin.class = org.cavaness.quartzbook.chapter8.ParentPlugin
接着,添加子插件,并按你想要的加载顺序排列,就是指定一个逗号分隔的插件列表:
org.quartz.plugin.parentPlugin.childPluginNames=org.quartz.plugins.history
.LoggingJobHistoryPlugin,org.quartz.plugins.history.LoggingTriggerHistoryPlugin
[译者 Unmi 注:注意,上面是写在一行里的,因页面排版本的原因写成两行了]
如代码 8.6 所示,ParentPlugin 拆开逗号分隔的字符串并以它们在列表中的顺序来加载插件。这看起来好像相当复杂,但却能很好的完成工作。将来的 Quartz 框架版本也许支持插件的按序加载机制,但是现在,ParentPlugin 工作的很好。
本文链接 https://yanbin.blog/quartz-job-scheduling-framework-8-4/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。