2006 年 7 月 17 日 開放服務(wù)網(wǎng)關(guān)協(xié)議 (Open Services Gateway Initiative),,簡稱 OSGi,為網(wǎng)絡(luò)服務(wù)定義了一個標準的、面向服務(wù)的計算環(huán)境,,為用戶提供了開放的,、面向服務(wù)組件的、易于部署的編程模型,,這個編程模型允許用戶將定義好的接口規(guī)范綁定到 OSGi 運行環(huán)境中的特定Service,,在構(gòu)件 SOA 面向服務(wù)為中心的企業(yè)應(yīng)用的過程中,OSGi 技術(shù)正發(fā)揮越來越重要的作用,。在本文中,,將介紹 OSGi 的概念和體系結(jié)構(gòu),并且利用 Eclipse 3.2 開發(fā)一個基于 OSGi 規(guī)范的服務(wù)應(yīng)用 Bundle,。通過學習本文,,讀者可以了解到如何開發(fā)和部署基于 OSGi 規(guī)范的 Bundle 應(yīng)用。 OSGi 聯(lián)盟建立于 1999 年,,是一個非贏利機構(gòu),,旨在建立一個開放的服務(wù)規(guī)范。OSGi 規(guī)范為網(wǎng)絡(luò)服務(wù)定義了一個標準的,、面向組件的計算環(huán)境,,它最初的目的就是為各種嵌入式設(shè)備提供通用的軟件運行平臺,屏蔽設(shè)備操作系統(tǒng)與硬件區(qū)別的中間件平臺,通過這個平臺,,可以對不同軟件商提供的應(yīng)用(OSGi 中稱為 Bundle)進行組件的生命周期管理的能力,,如應(yīng)用組件可以從運行中被安裝、升級或者移除而不需要中斷設(shè)備的操作,,應(yīng)用組件可以動態(tài)的發(fā)現(xiàn)和使用其他庫或者應(yīng)用程序,。由于 OSGi 技術(shù)具有服務(wù)組件模塊化、動態(tài)加載應(yīng)用等優(yōu)點,,正被越來越多的領(lǐng)域關(guān)注,,如嵌入設(shè)備制造業(yè)、汽車制造業(yè),、企業(yè)應(yīng)用等,。目前,OSGi 聯(lián)盟發(fā)布的最新的 OSGi 服務(wù)規(guī)范為 4.0,,讀者可以查閱參考資料了解詳細信息,。
OSGi 的體系架構(gòu)是基于插件式的軟件結(jié)構(gòu),包括一個 OSGi 框架和一系列插件,,在 OSGi中,,插件稱為 Bundle,其中,,OSGi 框架規(guī)范是 OSGi 規(guī)范的核心部分,,它提供了一個通用的、安全可管理的 Java 框架,,通過這個框架,,可以支持 Bundle 服務(wù)應(yīng)用的部署和擴展。Bundle 之間可以通過 Import Package 和 Require-Bundle 來共享 Java 類,,在 OSGi 服務(wù)平臺中,,用戶通過開發(fā) Bundle 來提供需要的功能,這些 Bundle 可以動態(tài)加載和卸載,,或者根據(jù)需要遠程下載和升級,。OSGi 體系結(jié)構(gòu)圖如圖 1 所示: 圖示1 OSGi 體系結(jié)構(gòu) 其中: Execution Environment: Bundle 應(yīng)用所倚賴運行的 Java 執(zhí)行環(huán)境,如 J2SE-1.4,、CDC-1.0 等都是可用的執(zhí)行環(huán)境,。 Modules: 模塊層定義了 Bundle 應(yīng)用的加載策略。OSGi 框架是一個健壯并且嚴格定義的類加載模型,。在大多數(shù) Java 應(yīng)用中,,通常只有一個單獨的 ClassPath,它包含了所有的 Java 類文件和資源文件,,OSGi基于Java技術(shù),,對于每個實現(xiàn)了 BundleActivator 接口的 Bundle 應(yīng)用,,為它生成一個單獨的 ClassLoader,使得 Bundle 應(yīng)用的組織更加模塊化,。 Life Cycle: 生命周期層可以動態(tài)地對 Bundle 進行安裝,、啟動、停止,、升級和卸載等操作,。該層基于模塊層,提供了一組 API 來控制 Bundle 應(yīng)用的運行時操作,。 Service Registry 和 Services: OSGi 服務(wù)層定義了一個集成在生命周期層中的動態(tài)協(xié)作模型,,是一個發(fā)布、動態(tài)尋找,、綁定的服務(wù)模型。一個服務(wù)通常是一個 Java 對象實現(xiàn)了特定的服務(wù)接口,,并且通過服務(wù)注冊,,被綁定到 OSGi 的運行環(huán)境中。Bundle 應(yīng)用可以注冊發(fā)布服務(wù),,動態(tài)綁定服務(wù),,并且在服務(wù)注冊狀態(tài)改變時,可以接受到事件消息等,。 Security: OSGi 的安全管理是基于 Java2 安全體系的,,貫穿在 OSGi 平臺的所有層中,它能夠?qū)Σ渴鹪?OSGi 運行環(huán)境中的 Bundle 應(yīng)用進行詳細的管理控制,。
在一個動態(tài)擴展的 OSGi 環(huán)境中,,OSGi 框架管理 Bundle 的安裝和更新,同時也管理 Bundle 和服務(wù)之間的依賴關(guān)系,。一個 Bundle 可能處于以下六個狀態(tài),,如圖 2 所示: 圖示 2 Bundle 狀態(tài)圖 INSTALLED:安裝完成,本地資源成功加載,。 RESOLVED:依賴關(guān)系滿足,,這個狀態(tài)意味該Bundle要么已經(jīng)準備好運行,要么是被停止了,。 STARTING:Bundle正在被啟動,,BundleActivator的start()方法已經(jīng)被調(diào)用但是還沒有返回。 STOPPING:Bundle正在被停止,,BundleActivator的stop()方法已經(jīng)被調(diào)用但是還沒有返回,。 ACTIVE:Bundle 被成功啟動并且在運行。 UNINSTALLED:bundle被卸載并且無法進入其他狀態(tài),。 Bundle接口定義了getState()方法來返回Bundle的狀態(tài),。
在 OSGi 平臺之上,,OSGi 聯(lián)盟定義了很多服務(wù)。服務(wù)是由一個 Java Interface 來定義的,,Bundle 可以實現(xiàn)這個接口并且把服務(wù)注冊到服務(wù)注冊表中去,,用戶可以從注冊表中找到需要的服務(wù)來使用,并且可以響應(yīng)特定服務(wù)的狀態(tài)改變,,如服務(wù)注冊和服務(wù)取消,。下面簡單介紹一下 OSGi Release 4 的一些主要服務(wù)。OSGi 框架提供了權(quán)限管理服務(wù),,包管理服務(wù)和最初加載系統(tǒng)服務(wù),。這些服務(wù)是 OSGi 框架的一部分并且管理著 OSGi 框架的運作。 Permission Admin Service:權(quán)限管理是指 Bundle 是否許可其他的 Bundle 的代碼,。當前的或者其他的 Bundle 的權(quán)限可以通過這個服務(wù)來操作,,一旦被設(shè)定權(quán)限,馬上就生效,。 Package Admin Service:Bundle 之間可以共享包內(nèi)的 Java 類和資源,,bundle 的更新可能需要 OSGi 框架重新解析 Bundle 之間的依賴關(guān)系,這個服務(wù)提供了 OSGi 服務(wù)平臺中包的共享狀態(tài)信息,。 Start Level Service:Start Level是指一些在特定Bundle起動之前必須運行或者初始化的一系列 bundle,。Start Lever Service 可以設(shè)置當前OSGi服務(wù)框架初始的Start Level,并且可以指定和查詢特定Bundle的Start Level,。
使用 Eclipse 開發(fā) Bundle 應(yīng)用 Equinox 框架是 Eclipse 組織基于 OSGi Release 4 的一個實現(xiàn)框架,,它實現(xiàn)了 OSGi 規(guī)范的核心框架和許多標準框架服務(wù)的實現(xiàn)。關(guān)于Equinox項目的詳細信息,,請查閱參考資料信息,。在本文中,我們使用 Eclipse 3.2 平臺開發(fā)兩個基于 OSGi 的 Bundle 應(yīng)用,,其中第一個 Bundle 應(yīng)用聲明,、實現(xiàn)并注冊了一個姓名查詢服務(wù),用于判斷所給姓名是否在已定義的查詢列表中,;第二個 Bundle 應(yīng)用查詢并引用第一個 Bundle 應(yīng)用所注冊的姓名查詢服務(wù),,如果用戶所給的姓名包含在查詢列表中,將返回正確的信息,,最后,,將開發(fā)的 Bundle應(yīng)用部署的 Equinox OSGi 框架中,用戶可以在 OSGi 控制命令行中輸入命令來查詢關(guān)于框架和 Bundle 應(yīng)用的具體信息,。讀者可以從參考資料中獲得本文 Bundle 應(yīng)用的源代碼,。 (1)創(chuàng)建 Plug-in Project,在 Eclipse 3.2 開發(fā)環(huán)境中,,從菜單欄選擇 File > New > Project... ,,打開 New Project 向?qū)?,可以看到有Plug-in Project創(chuàng)建向?qū)В瑒?chuàng)建一個Plug-in 項目,。項目名為 example 的 Bundle 應(yīng)用,,該應(yīng)用實現(xiàn)并注冊了一個姓名查詢服務(wù),實現(xiàn)了 BundleActivator 接口,。選擇 Equinox 框架作為 Bundle 應(yīng)用運行的 OSGi 服務(wù)平臺,。 圖示 3 Plug-in 項目向?qū)?/b> (2)實現(xiàn)OSGi服務(wù)通常需要兩個步驟,首先定義所提供服務(wù)的接口,,然后實現(xiàn)這個服務(wù)接口,。在本例中,我們創(chuàng)建一個姓名查詢服務(wù)用來查詢所給姓名是否有效,。首先定義姓名查詢接口NameService.java,。下面是該接口的源代碼: NameService Interface 源代碼
該服務(wù)接口很簡單,只包含一個需要實現(xiàn)的方法,。為了將服務(wù)接口和服務(wù)實現(xiàn)相分離,,方便其他 Bundle 引用該服務(wù),我們通常需要將該服務(wù)接口單獨放在一個包內(nèi),,本例中,,存放NameService.java 接口的 Java 包為 example.service,。接下來,,需要實現(xiàn) NameService 接口,并且注冊該服務(wù),。在本例中,,我們用內(nèi)部類實現(xiàn)了該接口,下面是該 Bundle 應(yīng)用的部分源代碼,。 Example Bundle部分源代碼
在start()方法中,,利用BundleContext注冊一個姓名查詢服務(wù),并且為該服務(wù)設(shè)置相關(guān)屬性以便服務(wù)查詢,。在實現(xiàn)姓名查詢服務(wù)時,,我們簡單定義了一個靜態(tài)數(shù)組用于存放有效的姓名信息。 (3)定義Bundle描述文件MANIFEST.MF,,Bundle應(yīng)用example的MANIFEST.MF文件如下: MANIFEST.MF文件信息
其中,,Bundle-Activator屬性指明了實現(xiàn)BundleActivator接口的類,該類用來啟動和停止Bundle應(yīng)用,。Export-Package屬性指定了該Bundle輸出的共享包,,該屬性可以使其他的Bundle應(yīng)用引用我們所定義的服務(wù)接口。 (4)創(chuàng)建項目名為exampleClient的Bundle應(yīng)用,,該應(yīng)用在OSGi平臺上查尋并引用example Bundle應(yīng)用已經(jīng)注冊的姓名查詢服務(wù),,然后從標準輸入讀入用戶所輸入的姓名信息,,判斷所輸入姓名是否有效。exampleClient應(yīng)用的部分源代碼如下,,讀者可從參考資料中獲得完整源代碼,。 ExampleClient Bundle部分源代碼
在Eclipse平臺中,選擇File-->Export...菜單,,將開發(fā)的example和exampleClient兩個Bundle應(yīng)用導(dǎo)出成Jar文件,,以便將它們部署到OSGi服務(wù)平臺中。選擇將要運行的Bundle應(yīng)用,,鼠標右鍵點擊,,在彈出菜單中,選擇Run AS-->Equinox FrameWork來啟動OSGi服務(wù)平臺,。在Equinox啟動配置控制臺中,,可以為Bundle應(yīng)用設(shè)置默認的Start Level和Bundle應(yīng)用是否需要自動啟動等選項。在本例中,,為了講解如何安裝及啟動Bundle應(yīng)用,,只將example Bundle應(yīng)用設(shè)為自動啟動,而exampleClient Bundle應(yīng)用需要我們用命令安裝及啟動,。 當OSGi Equinox FrameWork啟動后,,在OSGi控制命令臺中輸入ss命令,可以查看OSGi服務(wù)平臺中已經(jīng)安裝的Bundle應(yīng)用信息及其狀態(tài),。如圖4所示,,可以看到當前OSGi服務(wù)平臺中有兩個Bundle處于Active狀態(tài),其中,,system.bundle_3.2.0.v20060328為OSGi框架的系統(tǒng)Bundle,,而example_1.0.0為注冊姓名查詢服務(wù)的Bundle應(yīng)用,1.0.0為Bundle應(yīng)用的版本號,。 圖示4 Bundle信息查詢 在OSGi控制命令臺中利用install命令安裝exampleClient Bundle應(yīng)用,,用ss命令查看安裝后的Bundle應(yīng)用信息及其狀態(tài)。如圖5所示: 圖示5 安裝Bundle 在OSGi控制命令臺中利用start命令安裝exampleClient Bundle應(yīng)用,,用戶可輸入姓名,,利用姓名查詢服務(wù)來判斷所輸入姓名是否有效,,用ss命令查看啟動后的Bundle應(yīng)用信息及其狀態(tài),。如圖6所示: 圖示6 啟動Bundle 用戶在在OSGi控制命令臺中,,可利用stop命令來停止指定的Bundle應(yīng)用,close命令用來停止并退出OSGi控制命令臺,。關(guān)于OSGi Equinox FrameWork控制臺命令的詳細信息,,可查看參考資料。
OSGi服務(wù)框架提供了開放的,、面向服務(wù)的,、易于部署的編程模型,,在構(gòu)件面向服務(wù)為中心的企業(yè)應(yīng)用的過程中,OSGi 技術(shù)正發(fā)揮越來越重要的作用,。目前,,Eclipse 3.2 體系架構(gòu)是參照OSGi實現(xiàn)的,Equinox框架是 Eclipse 組織基于OSGi Release 4 的一個實現(xiàn)框架,,它實現(xiàn)了OSGi 規(guī)范的核心框架和許多標準框架服務(wù),。在本文中,我們利用Eclipse 平臺開發(fā)了兩個Bundle應(yīng)用,,并且在Bundle應(yīng)用中,,聲明、實現(xiàn),、注冊并引用了一個簡單的服務(wù),,最后,將Bundle應(yīng)用部署到Equinox OSGi服務(wù)框架中,。通過本文,,讀者可以了解如何開發(fā)和部署基于OSGi規(guī)范的Bundle應(yīng)用。 |
|