天天看點

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

繼續閱讀