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