天天看点

kettle源代码解析(1)——plugin系统分析1      plugin机制

1      plugin机制

1.1  为什么要用插件?

其实所有类型的plugin系统(如nutch插件)都是为了获得如下能力

1)        插件self-contained(自包含)和out-of-box(开箱即用,即:拷贝后重启kettle即可使用,于运行时动态发现、加载和动态调用)的能力。

2)        on-demand部署能力,根据需要仅仅部署需要的插件,减少release包大小,加快部署、传输和运行速度。

3)        分离关注点,方便插件与引擎并行开发。

1.2  插件定义

kettle源代码解析(1)——plugin系统分析1      plugin机制

图1与插件注册和查找机制相关的类图

1.2.1  PluginTypeInterface

kettle源代码解析(1)——plugin系统分析1      plugin机制

图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所示。

kettle源代码解析(1)——plugin系统分析1      plugin机制

图3 与PluginType、BasePluginType及其子类继承关系类图

BasePluginType类图如图 4所示。

kettle源代码解析(1)——plugin系统分析1      plugin机制

图 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  插件注册与查找

kettle源代码解析(1)——plugin系统分析1      plugin机制

图 5插件注册UML序列图(省略了其他PluginType的add,仅关注Step和JobEntry)

1.4 相关Design Pattern

1.4.1  Singleton

kettle源代码解析(1)——plugin系统分析1      plugin机制

图 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

kettle源代码解析(1)——plugin系统分析1      plugin机制

图 7 BasePluginType的searchPlugins方法为Template Method

继续阅读