Quartz Job Scheduling Framework[翻译]第八章. 使用 Quartz 插件 (第四部分)

四. 使用多个插件


你喜欢多少个,就可以在 quartz.properties 文件中注册多少个插件。然而,加载和初始化的顺序却不能保证,因为 Quartz 加载先把所有的属性到一个 Map 中,然后按照从 Map 中取出的顺序遍历插件。

为规避这一限制,你可以创建一个 Quartz 插件作为父插件,然后以给定的顺序加载其他多个插件。代码 8.6 显示了 ParentPlugin 长什么样子。

代码 8.6. ParentPlugin 能以特定的顺序加载子插件
  1package org.cavaness.quartzbook.chapter8;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5import java.util.StringTokenizer;
  6
  7import org.apache.commons.logging.Log;
  8import org.apache.commons.logging.LogFactory;
  9import org.quartz.Scheduler;
 10import org.quartz.SchedulerConfigException;
 11import org.quartz.SchedulerException;
 12import org.quartz.spi.SchedulerPlugin;
 13
 14public class ParentPlugin implements SchedulerPlugin {
 15    private static Log logger = LogFactory.getLog(ParentPlugin.class);
 16
 17    // A list of child plug-ins
 18    private List childPlugins = new ArrayList();
 19
 20    private String childPluginNames;
 21
 22    private String pluginName;
 23
 24    private Scheduler scheduler;
 25
 26    /**
 27     * Default no-arg Constructor
 28     *
 29     */
 30    public ParentPlugin() {
 31    }
 32
 33    /**
 34     * Pass the initialize call on to the child plug-ins.
 35     *
 36     * @throws SchedulerConfigException
 37     *             if there is an error initializing.
 38     */
 39
 40    public void initialize(String name, final Scheduler scheduler)
 41              throws SchedulerException {
 42
 43         this.pluginName = name;
 44         this.scheduler = scheduler;
 45
 46         logger.info("Searching for child plugins to load");
 47
 48         // The child plug-ins are comma-separated
 49         StringTokenizer tokenizer =
 50              new StringTokenizer(childPluginNames, ",");
 51
 52         while (tokenizer.hasMoreElements()) {
 53              String pluginClassname = tokenizer.nextToken();
 54
 55              try {
 56                   Class pluginClass =
 57                        Class.forName(pluginClassname);
 58
 59                   Object obj = pluginClass.newInstance();
 60
 61                   // Make sure the specified class is a plug-in
 62                   if (obj instanceof SchedulerPlugin) {
 63                        // Initialize the Plugin
 64                        SchedulerPlugin childPlugin =
 65                              (SchedulerPlugin) obj;
 66
 67                             logger.info("Init child Plugin " +
 68                                  pluginClassname);
 69
 70                        childPlugin.initialize(pluginClassname,
 71                             scheduler);
 72
 73                        // Store the child plug-in in the list
 74                        childPlugins.add(childPlugin);
 75                   } else {
 76                        // Skip loading class
 77                        logger.error("Class is not a plugin " +
 78                             pluginClass);
 79                   }
 80
 81              } catch (Exception ex) {
 82                   // On error, log and go to next child plug-in
 83                   logger.error("Error loading plugin " +
 84                        pluginClassname, ex);
 85              }
 86         }
 87    }
 88    public void start() {
 89         // Start each child plug-in
 90         int size = childPlugins.size();
 91         for (int i = 0; i < size; i++) {
 92              SchedulerPlugin childPlugin =
 93                   ((SchedulerPlugin) childPlugins.get(i));
 94
 95              logger.info("Starting Child Plugin " + childPlugin);
 96              childPlugin.start();
 97         }
 98    }
 99
100    public void shutdown() {
101         // Stop each child plug-in
102         int size = childPlugins.size();
103         for (int i = 0; i < size; i++) {
104              SchedulerPlugin childPlugin =
105                   ((SchedulerPlugin) childPlugins.get(i));
106
107              logger.info("Stopping Plugin " + childPlugin);
108              childPlugin.shutdown();
109         }
110    }
111
112    public String getPluginName() {
113         return pluginName;
114    }
115
116    public void setPluginName(String pluginName) {
117         this.pluginName = pluginName;
118    }
119
120    public String getChildPluginNames() {
121         return childPluginNames;
122    }
123
124    public void setChildPluginNames(String childPluginNames) {
125         this.childPluginNames = childPluginNames;
126    }
127}

代码 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's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。