搶佔先機
VMware 提供培訓和認證,助你加速前進。
瞭解更多SpringSource 應用平臺由 OSGi Bundle 構建而成,並支援同樣由 OSGi Bundle 構建的應用。該平臺支援 OSGi 的標準特性,但也支援一些額外的清單頭部。有幾個人問過 為什麼 SpringSource 添加了專有頭部?
和 新頭部的語義是什麼?
,所以這篇博文解釋了 Import-Library 和 Import-Bundle 的背景動機和語義。
因此,精通 OSGi 的開發者可以將該平臺用作標準的 OSGi 容器,並受益於平臺特性,例如:
嗯,這個過程中的一些步驟相對容易,特別是如果遵循了良好的軟體工程實踐並且程式碼已經組織成服務、領域和基礎設施元件。這些元件可以轉換為 Bundle,並且它們之間的依賴關係可以使用 META-INF/MANIFEST.MF 中的標準 OSGi Import-Package 和 Export-Package 頭部來表達。
更困難的一步是表達對企業框架(如 Spring 和 Hibernate)的依賴。使用標準的 OSGi Import-Package 和 Require-Bundle 頭部來表達這些依賴關係是完全可行的,如果你的目標是建立可以在其他 OSGi 容器中執行的 OSGi Bundle,這正是你應該做的,但這種方法有一些隱含成本。
首先,開發者必須精確地決定一個給定框架包含哪些包。僅僅匯入應用程式碼使用的包是不夠的,因為一些企業框架在應用載入時會將更多的依賴編織到應用的位元組碼中。開發者必須透過反覆試驗來發現需要匯入哪些額外的實現包,以確保編織後的應用行為正確。
其次,從一個框架版本遷移到下一個版本是一項繁瑣的任務,因為構成該框架的精確包集合可能已經改變。編織所需的附加包通常未由公共契約定義,因此可能會發生變化。
此外,由此產生的包匯入並不能恰當地體現設計意圖,這使得未來維護或擴充套件應用更加困難。
我們真的不想把這些負擔強加給使用者,所以我們建立了一些額外的 SpringSource 應用平臺特定的清單頭部,Import-Library 和 Import-Bundle,作為表達對企業框架依賴的便捷方式。正如你將在下面看到的,這些頭部實際上只是 語法糖
,它們最終會被轉換為標準的 OSGi 包匯入。
Import-Library: <librarySymbolicName>;version=<versionRange>其中 <librarySymbolicName> 是庫的
符號名,而 <versionRange> 是使用 OSGi 版本範圍表示法表示的庫的可接受版本範圍。庫定義指定了庫的符號名和版本,這兩者共同唯一標識了平臺上的庫。
如果你不熟悉 OSGi 版本範圍表示法,目前最常用的形式是最低版本範圍,例如 2
,表示 版本 2 或更高
,以及 半開
範圍,例如 [2.2.1,2.2.2)
,表示大於等於 2.2.1 且小於 2.2.2 的任何版本。如果省略了 version=<versionRange>(當然也包括分號分隔符),則預設範圍包含所有版本。
對於每個庫匯入,平臺會選擇具有給定符號名並在平臺倉庫中可用且在給定版本範圍內的最高版本庫。然後,平臺會將該庫匯入替換為一組包匯入,這些包匯入與該庫 Bundle 匯出的所有包匹配。平臺會檢測一個 Bundle 匯入兩個或多個匯出相同包的庫的情況,併發出適當的日誌訊息,然後阻止安裝該匯入 Bundle。
例如,以下頭部匯入了版本在 2.5.4(含)到 2.5.5(不含)之間的某個版本的 Spring Framework 庫:
Import-Library: org.springframework.spring;version="[2.5.4,2.5.5)"
:=,它表示一個
指令,用於修改清單頭部的語義,與分隔符
=不同,後者表示一個
匹配屬性,例如 version。
Import-Library: <librarySymbolicName>;version=<versionRange>;resolution:=optional
如果未指定 resolution,或者指定為 mandatory,則如果不存在具有給定符號名且版本在給定範圍內的庫,包含該匯入庫頭部的 Bundle 將無法安裝。但如果指定了 resolution:=optional,則如果找不到合適的庫,該庫匯入將被忽略。
例如,以下頭部匯入了版本從 2.5 開始的某個版本的 Spring Framework 庫,但如果沒有合適的庫可用,則會被忽略:
Import-Library: org.springframework.spring;version="2.5";resolution:=optional
Import-Library: org.foo.p;version="[1,2)",org.bar.q;version="[2,3)"
正如你所預期的,對於每個匯入的 Bundle,平臺會選擇具有給定符號名並在平臺倉庫中可用且在給定版本範圍內的最高版本 Bundle。然後,平臺會將該 Bundle 匯入替換為一組與該 Bundle 匯出的包匹配的包匯入。
例如,以下頭部匯入了 Hibernate 物件關係對映 Bundle:
Import-Bundle: com.springsource.org.hibernate;version="[3.2.6,3.2.7)"
嗯,我們希望 Require-Bundle 保留其標準語義,包括合併拆分包的能力。但我們希望 Import-Library 和 Import-Bundle 具有與 Import-Package 相同的底層語義,從而避免拆分包的複雜性。
我們還預計,隨著平臺的不斷發展,我們將需要為 Import-Library 和 Import-Bundle 新增更多指令,這些指令不適合新增到 Require-Bundle。
對於希望利用平臺頭部,但又需要生成能在其他 OSGi 容器上執行的 Bundle 的使用者,我們計劃提供一個工具,將 Import-Library 和 Import-Bundle 語法糖替換為等效的標準包匯入。
我們還將與 OSGi Alliance 的同事討論新的清單頭部,以確定是否存在適合 OSGi 未來解決的通用需求。