在讀本文之前,您應該對基于Equinox的開發有一定的了解,如果您還不太清楚,請參考基于Equinox開發HelloWorld一文。 本文講到的例子是仿照網上甚為流行的一個例子,但苦于一直未找到源碼,網上貼的都是一些轉帖,代碼片段,估計初學者很難將其還原并調通!我最開始弄這個咚咚的時候,其過程之痛苦,難以言喻,所以想著仿照該例子的設計,給予實現,文后貼出源碼,希望能幫到大家。 該例子是一個關于計算器的實例,osgi.example.compute bundle(下文簡稱compute bundle)提供了統一的計算接口:Compute,另外兩個bundle分別為osgi.example.compute.add(下文簡稱add bundle)和osgi.example.compute.multiply(下文簡稱multiply bundle),在這兩個bundle中,各自對compute bundle進行不同的實現,一個實現加法,一個實現乘法。另外還有一個服務消費者osgi.example.compute.consumer bundle(下文簡稱consumer bundle),consumer bundle負責消費add bundle和multiply bundle提供的服務。上述4個bundle之間的關系如下圖所示:
創建4個bundle之后的工程目錄如下圖所示:
通過該示例,將演示如何利用Spring DM發布和調用OSGi服務,同時還將演示OSGi的動態服務調用能力。 1. bundle osgi.example.compute compute bundle只提供一個接口——Compute,因此無需依賴更多的bundle,只需最基本的osgi即可。因為不涉及注冊資源之類的,所以也無需Activator入口類。 Computer接口源代碼如下所示:
add bundle是對compute bundle的具體服務實現,在MANIFEST.MF文件需要引入osgi.example.compute包;當然也可以通過添加依賴bundle的形式,即不引入包,而直接在Required Plug-ins中添加compute bundle。如下圖所示:
注意:OSGi官方指出,當需要用到其他bundle的類型時,不提倡依賴bundle,應該盡可能采用Import-package的方式引入包,因為依賴bundle可能在加載bundle的時候發生問題。
通過引入osgi.example.compute包,osgi.example.compute bundle被加到了add bundl的classpath當中,解決了開發時期的類型識別問題。 這樣一來,在add bundle中就能使用compute bundle中的接口了,Computer接口的實現如下:
Compute的實現已經實現了,那么如何將其發布出去呢?這個是由Spring DM負責,Spring DM利用OSGi命名空間下的<service>元素將bean導出為OSGi服務。最簡單的形式為:
從示例中可以看出,beanToPublish被service元素聲明導出。 另外,service結點還有一些高級屬性,如depends-on、context-class-loader、ranking等待,詳情請看spring dm reference。 首先,需要在add bundle的工程根目錄下的”META-INF”的文件夾下創建一個文件夾,取名”spring”,Spring DM能夠自動解析該文件夾下所有的spring配置文件。spring配置文件的具體內容如下所示:
該bundle和add bundle相似,在這就不贅述了。 4. bundle osgi.example.compute.client
顧名思義,該bundle將作為add 、multiply兩個bundle的客戶bundle,演示如何導入服務。 OSGi的測試工作比較麻煩,這方面還沒研究,在這里利用spring實例化bean的時期,從構造函數入手,對服務進行測試。Client類的實現很簡單,如下所示:
另外,因為client用到了其他幾個bundle的類型,所以需要導入相應的包,步驟在上面已有講到。 spring dm靠<reference>元素來引入服務,最簡單的形式如下所示:
如果需要用到該服務,如某個bean包含一個com.xyz.MessageService屬性,則配置該bean如下所示:
需要勾選中spring bundle版(2.5.6),spring dm的幾個核心包:core、extender、io再點validate bundles按鈕,校驗是否已全部選中其依賴的bundle。然后即可點擊運行了。 運行之后,我們發現控制臺輸出結果: The Sum is---11 通過ss命令,如下: 5 ACTIVE osgi.example.compute.multiply_1.0.0 6 ACTIVE osgi.example.compute.add_1.0.0 7 ACTIVE osgi.example.compute.client_1.0.0 將6停掉:stop 6 然后再refresh 7,控制臺輸出如下結果: The Multiply is---30 通過 ss 命令,如下: 5 ACTIVE osgi.example.compute.multiply_1.0.0 6 RESOLVED osgi.example.compute.add_1.0.0 7 ACTIVE osgi.example.compute.client_1.0.0 現在multiply處于運行狀態,而add已經被停止,所以client導入的服務實際是由multiply提供的。
6. 總結
通過該文檔,我們已經清楚了,如何使用Spring DM導出、導入服務。Spring DM的一些高級特性請查閱spring dm reference。 附件:osgi.example.compute.rar