1 plugin机制
1.1 为什么要用插件?
其实所有类型的plugin系统(如nutch插件)都是为了获得如下能力
1) 插件self-contained(自包含)和out-of-box(开箱即用,即:拷贝后重启kettle即可使用,于运行时动态发现、加载和动态调用)的能力。
2) on-demand部署能力,根据需要仅仅部署需要的插件,减少release包大小,加快部署、传输和运行速度。
3) 分离关注点,方便插件与引擎并行开发。
1.2 插件定义
图1与插件注册和查找机制相关的类图
1.2.1 PluginTypeInterface
图2与PluginTypeInterface类图
PluginTypeInterface的“职责”是从众多plugin中抽象出“种类(type)”来,规定了每个“种类”的plugin需要具有如下特征:
1) 标识,即id和name,使得PluginRegistry(之后介绍)可以按照“标识”进行查找plugin。
2) 从何处加载该类plugin,见5.2.2之2)。
1.2.2 BasePluginType
BasePluginType是PluginTypeInterface的直接实现,kettle按照每种PluginType的“功能”不同,定义了22种具体的实现类,如图 3所示。
图3 与PluginType、BasePluginType及其子类继承关系类图
BasePluginType类图如图 4所示。
图 4与BasePluginType类图(只截取了关心的部分)
结合图 3和图 4可以看出,BasePluginType的“职责”如下:
1) 为PluginTypeInterface接口提供了默认实现。
2) 采用Template Method模式(后面介绍),在BasePluginType为searchPugins()方法建立了骨架,并为其中“不变(参见“变化点”)”的部分——即registerPluginJars()提供了默认实现。BasePluginType中为searchPugins()方法提供了默认实现,默认情况下,所有种类的plugin从3个地方加载:
a) registerNatives()
b) registerPluginJars()
c) regsiterXmlPlugins()
1.2.3 PluginRegistry
未完,待续...
1.3 插件注册与查找
图 5插件注册UML序列图(省略了其他PluginType的add,仅关注Step和JobEntry)
1.4 相关Design Pattern
1.4.1 Singleton
图 6 PluginRegistry实现为Singleton
PluginRegistry负责为了全局唯一的已注册的plugin视图,并且未重启应用(例如Spoon)之前,该视图不会改变,故需要设计成Singleton。
确切的说,kettle将PluginRegistry实现成了“饿汉模式”,符合其3个特征:
1) 只有private构造函数。
2) 定义了private static PluginRegistry类型的字段,并且定义时就调用private构造函数初始化。
3) 定义了static类型获取唯一PluginRegistry实例的方法getInstance()。(该方法叫什么名字不重要)
1.4.2 Template Method
图 7 BasePluginType的searchPlugins方法为Template Method