1. 程式人生 > >OSGI中的service依賴關系管理

OSGI中的service依賴關系管理

eight 標準規範 全部 make 依賴管理 ase 概念 includes .html

眾所周知。對於高動態高可擴展的應用,OSGI是一個很好的平臺。可是。也因此添加了復雜性。開發中對service的依賴變得復雜。

這也是service的關系管理成為OSGI中一個很重要的部分,我們來看看OSGI中service依賴關系管理的方式。

篇幅原因,僅僅關註發展歷程,不具體介紹每一個方式的具體實現細節。

概括的說。眼下在OSGI中主要有下面幾種service依賴關系管理的方法:

1. Service listener
2. Service binder
3. Dependency Manager
4. Declarative Services
5. iPOJO
6. blueprint

1) Service Listener

這是OSGI中原生的service依賴管理機制,是最簡單直接的方式,其基本原理很easy,標準的註冊/查找:

1. 被依賴的bundle通過BundleContext.registerService()方法註冊服務到系統中
2. 使用依賴的bundle在start時通過BundleContext的getServiceReferences()/getService()來查找依賴的service
3. 使用依賴bundle通過BundleContext.addServiceListener()來分別註冊ServiceListener
4. 在被依賴的bundle/service狀態發生變化時, 使用依賴bundle通過ServiceListener的serviceChanged()得到通知並作出調整。

在這樣的方法中,使用依賴的Service必須進行大量的編碼工作來完畢對依賴的service的關系管理,須要處理瑣碎細節如各個Service的執行時狀態變化。為了降低工作量,OSGI設計了ServiceTracker來簡化對依賴service的編碼工作。即ServiceTracker將負責處理上述步驟中的2/3/4。

經過ServiceTracker優化後的Service Listener機制。還是存在一些缺點:
技術分享
1. 編碼量還是不小,尤其對於依賴較多的場景

2. Activator 還是太復雜了,雖然已經非常努力的試圖簡化
對於一些業務邏輯簡單的service,假設依賴的service比較多,那麽Activator的邏輯和代碼實現遠比service本身的邏輯和實現要復雜。這違背了我們使用框架簡化開發的初衷。

3. Activator對測試不利
這個是Activator的復雜性造成的,因為Activator中存在大量的依賴處理邏輯,理所當然的會添加測試的復雜性。

總結說。Service Listener 機制下。管理service依賴對於開發人員來說全然是個重體力活: 非常重要。常常要做,easy出現錯誤, 出錯時不easy測試。並且,這些工作都不是service 業務邏輯的組成部分。不能帶來直接收益。簡言之,吃力不討好,一不小心就搬石頭砸自己的腳。

更重要的。從分工的角度上將。開發者應該將很多其它的精力投入與應用的邏輯,而不是OSGI的底層實現機制。因此,從2000之後,就陸續有人開始考慮對此改進。

2) Service binder

Service binder OSGI針對這個問題的一個嘗試,基本出發點很明白:希望找到一個通用的方法來簡化OSGI下的動態service依賴管理.

最初開始這個工作的是兩位大牛。Richard S. Hall和Humberto,大概在2002年的時候開發完畢。

看我們看Service binder是怎麽做的。基本步驟為:

1. 提供一個org.apache.felix.servicebinder.GenericActivator;
如今bundle的Activator僅僅要簡單的繼承GenericActivator就能夠了,全部的代碼實如今GenericActivator提供,降低代碼的目標順利達成。這個能夠說足夠簡單到沒有辦法再簡單了。
2. 通過metadata.xml 來實現service的依賴註入

3. 詳細的service的實現類基本就是一個幹凈的POJO了
當然還是須要實現bind-method/unbind-method 兩個方法。好在這個是通過metadata.xml來做映射,不是另外提供接口定義,因此勉強避開了"侵入"的問題。

Service binder 機制在降低Activator方面成效顯著,可是引入的metadata.xml文件似乎又帶來了新的問題。xml配置文件的可維護性個人感覺值得懷疑。用過EJB的同學都明確。EJB的部署文件有多令人煩惱。

當然Service binder 的思路很的正確:通過引入了自己主動化的service依賴關系管理。簡化開發,同意開發者能夠集中精力在service的實現上,而不是疲於處理依賴關系管理。

Service binder的實現似乎並沒有被推廣開。由於非常快OSGI就在2004年的OSGI R4規範中引入了Declarative Services。因此Felix也就終止了對Service binder的興許支持。

3) Dependency Manager

繼Service binder之後,Felix又提供了名為Dependency Manager 的service依賴管理方式。對照Service binder,個人感覺這個Dependency Manager 僅僅是針對Service binder的一個改進:將metadata.xml 文件取消,由新引入的DependencyManager來實現metadata.xml 文件的功能。原來在metadata.xml 文件裏的配置轉變為在Activator中通過代碼調用DependencyManager來實現.

Dependency Manager事實上現的方式為:

1. 提供org.apache.felix.dependencymanager.DependencyActivatorBase
bundle的Activator須要繼承DependencyActivatorBase,並實現DependencyActivatorBase要求的init()/destroy()方法
2. 在init()中,能夠通過DependencyManager 對象來註冊服務,並註明依賴。

3. 詳細的Service類能夠是POJO。DependencyManager 通過反射來註入依賴的service。

Felix 官方給出了一個Dependency Manager的使用演示樣例
http://felix.apache.org/site/dependency-manager-usage.html
從演示樣例上看,對service的依賴管理已經簡化了很多。

這裏另一個05年的介紹Dependency Manager的 presentation:
http://felix.apache.org/site/presentations.data/DependencyManagement.pdf

4) Declarative Services

2004年公布的OSGi的4.0版本號中,增加了Declarative Services。據說是從Service Binder進化而來。

Declarative Services的實現方式和Service Binder的確很相似:

1. 相同是須要一個xml文件來配置
在 bundle manifest中添加Service-Component 的header
提供的功能和Service Binder非常類似。配置方法也非常接近。

2. 相同的提供bind/unbind 方法的配置
對於每一個依賴的service,都能夠在配置文件裏通過指定bind/unbind 方法來處理依賴的狀態變化。

此外,Declarative Services 提供兩個特殊的lifecircle方法:
protected void activate(ComponentContext context)
protected void deactivate(ComponentContext context)
假設service實現類提供了這兩個方法,則Declarative Services 會自己主動識別並調用這兩個方法。註意這兩個方法沒有接口定義進行強約束。僅僅是一個約定而已。預計是為了避免OSGI對service的侵入。

Declarative Services 是OSGI規範的一部分,因此Declarative Services的支持自然是各個OSGI實現都提供的。

從功能上將,Declarative Services 基本已經不錯了,可是大牛們的腳步並未就此停住。

5) iPOJO

2005年,Richard 開始考慮使用字節碼生成技術來進行創建組合服務的改進。另外一個牛人Peter Kriens也相同的工作並實現了一個原型。
2006年,Clement Escoffier 和 Richard 開始開發iPOJO。合並了Peter Kriens之前的工作內容,這就是iPOJO的由來。

對於iPOJO的定義。Felix的iPOJO頁面有例如以下說明:iPOJO是一個server組件執行時,目標在於簡化OSGI應用開發。原生支持全部的OSGI活力。給予POJO的概念,應用邏輯開發簡單。

非功能性的屬性在執行時被註入到組件中。

相同看看Felix對iPOJO長處的說明:

1. 組件被作為POJO開發,不須要其它不論什麽東西
2. 組件模塊是可擴展的,因此能夠自由的適應須要
3. 標準組件模型管理service 供應和service 依賴,所以能夠要求其它不論什麽OSGI服務來創建組合服務,
4. iPOJO管理組件實例的生命周期和環境動態
5. iPOJO提供一個強力的組合系統來創建高度動態的應用
6. iPOJO支持註解,xml或者基於Java的API來定義組件

能夠看到iPOJO的功能遠比之前的幾個解決方式要強大,除了支持Declarative Services已經實現的功能外,還提供了強大的註解支持。並且實現了組合系統。這些對於開發大型的復雜應用時很實用的。

Richard 在他的presentation談到iPOJO 的設計思路:

1. Make things simple / 讓事情簡單
2. Follow POJO philosophy / 遵循POJO的哲學
3. Employ byte code manipulation techniques / 使用字節碼操縱技術
4. Be as lazy as possible / 盡可能的偷懶

眼下的iPOJO還在繼續發展中。最新的一個版本號iPOJO 1.6.0在2010-04-25公布。
6) blueprint

blueprint 是OSGI為了解決上述問題的最新嘗試。在去年剛公布的OSGI v4.2 規範中新增加了 Blueprint Container 的規範內容。

提到blueprint 就不能不提到spring Dynamic Modules,blueprint 能夠覺得是Spring Dynamic Modules版本號的改進和標準化。

SpringDM 1.x版本號實現了Spring Dynamic Modules for OSGi,在Spring Dynamic Modules被標準化為Blueprint Container 規範後,新的SpringDM 2.x 則成為Blueprint的參考實現。

blueprint 的使用實行很類似標準的spring IOC容器,比方相同的使用xml配置文件。僅僅是從ioc 的applictionContext xml變成了Blueprint XML。而Blueprint XML的配置方式和spring 有驚人的相似。
舉例,最簡單的bean:

基本就是照搬spring IOC的方式。對於熟悉spring的開發者來說無疑是個好消息。起碼學習曲線平緩了。

因為是OSGI的標準規範。blueprint 眼下的支持還是不錯的,除了上面說的SpringDM外。還有Geronimo Blueprint Container 和 Apache Felix Karaf 都提供了對blueprint的支持。

總結。從上述的發展歷程上看,OSGI中的service依賴關系管理方式,經歷了從簡單原始到逐漸成熟強大的過程,前後經歷了大概10年的時間.
很多其它詳情

OSGI中的service依賴關系管理