InfoQ 有一個關於 SpringSource Application Platform 釋出反響的討論帖。Michael Burke 在該帖中提出了一個很好的問題,可以概括為“撇開圍繞 OSGi 的炒作不談,如果我將一個當前打包為 EAR 的應用程式移植到 OSGi bundle 中,我能期待看到哪些好處?”。
我開始在 InfoQ 帖中回答這個問題,但我的回答太長,不適合作為評論,所以在這裡詳細闡述。
這個問題很好。基於 OSGi 的應用程式與傳統的基於 JEE EAR 的應用程式之間的主要區別在於模組化程度更高。所以問題變成了,這種改進的模組化能否帶來任何好處,如果能,具體是什麼?"設計規則,模組化的力量" 這本書對這個問題進行了非常詳盡的論述。這本書提供了很好的背景知識,但我感覺 Michael 可能在尋找一些比書中更不理論化的東西!讓我們將模組化的好處分為兩類:開發時應該期待的好處,以及執行時應該期待的好處。
開發時好處。
- 開發時(以及執行時)嚴格執行模組邊界
OSGi 具有確保開發團隊遵守模組邊界的機制。使用 OSGi,模組匯出的型別需要明確宣告(如果未匯出,則不可見),模組的依賴關係也需要明確宣告(這可以包含版本範圍相容性資訊)。這意味著在使用開發工具時,團隊無法透過程式碼自動完成意外地違反模組邊界,並且在執行時,OSGi 服務平臺會阻止一個模組看到另一個模組的私有內部實現。因此,你的應用程式架構在開發週期中保持整潔和受到保護,而不是透過(通常是無意的)不必要的耦合而緩慢崩潰。- 一種切實可行的服務導向架構,用於管理模組間的服務依賴。
模組間的依賴當然不只侷限於型別——模組還需要提供服務(可以理解為 Spring bean)供其他模組使用,並且可能依賴於其他模組提供的服務(再次理解為 Spring bean)。你的應用程式與其本質上是一個大型應用程式上下文,不如將其視為透過本地服務登錄檔互動的一組對等上下文。Spring bean(元件)對模組來說是私有的,除非明確匯出。模組間的 bean 引用由執行時管理。這再次意味著,在模組上工作的開發人員可以自由地進行任何他們喜歡的內部更改,只要外部契約(釋出的 bean、匯出的型別)保持不變。使用 Spring Dynamic Modules 時,模組的匯入和匯出型別以及匯入和匯出服務都是宣告式指定的(前者在 OSGi manifest 中,後者在 Spring 配置檔案中)。- 更好地按照你想要的方式組織開發團隊
“組織結構追隨架構”。將一個團隊分配給特定的一個或多個模組進行工作很容易。但要求一個團隊實現一個跨越許多模組的功能則困難得多。因此,自然而然地,你的技術架構(如何將系統劃分為模組)決定了你的組織結構——即你如何在團隊和個人之間有效地劃分工作。應用程式模組化上的更大靈活性意味著團隊結構上的更大靈活性。有時你會看到相反的情況:“架構追隨組織結構”。這種情況往往發生在由一些地理位置相近的個體組成分散式團隊時。為了做出合理的任務分配,如果可能的話,你會希望將模組與地點對齊。因此,如果你不能移動人員,那麼在合理程度上你的架構就受到你的組織的支配。在模組分解方面擁有更大的靈活性,你就越有可能找到適合你的方案。- 更快的團隊開發
當模組具有清晰的邊界——定義良好的外部介面、詳細指定的依賴關係和受保護的內部實現時,負責這些模組的團隊可以更容易地並行開發,而不會意外地相互干擾。詳細指定的互動更容易進行樁測試 (stub) 和模擬測試 (mock),也更容易整合。這應該會帶來更高效的團隊和更快的開發週期。- 更快的測試周期
當你在容器內進行測試時,SpringSource Application Platform 的 Eclipse 開發工具利用了 OSGi 服務平臺在執行系統中動態更新給定模組的能力。與你的專案關聯的增量構建器會在你做出任何更改時自動更新正在執行的平臺例項中的模組。這可以是任何更改——程式碼或其他。例如,如果你在 Web 層工作,持續與你的 Web 應用程式互動並邊測試邊進行,那麼每次更改時 Web 模組都會被重新整理——你無需等待你的持久化層每次都被重新初始化。Spring Dynamic Modules 提供的對 bundle(模組)間服務引用的智慧管理確保所有模組間連結在重新整理後得到修復。這種開發體驗非常令人著迷:我已經警告過你!- 作為依賴管理一部分的版本控制支援
當一個模組指定其依賴項時,它可以指定一個版本範圍(可以限定為單個版本),表明它相容的依賴項版本。OSGi 允許在執行時同時存在一個 Java 包的多個版本。這使得團隊 A 需要某個庫的版本 x,而團隊 B 需要同一個庫的版本 y(且 x 和 y 不相容)的場景成為可能。只要模組 A 和 B 之間不需要交換該庫中的型別,這就可以無障礙地工作。如果模組 A 和 B確實需要在它們之間交換型別,那麼 OSGi 服務平臺會在部署時而不是執行時檢測到這個潛在衝突(假設兩個模組的 manifest 檔案已正確生成)。- 減少障礙
與我的其他觀點(這些觀點普遍適用於 OSGi)不同,這一點是 SpringSource Application Platform 所特有的。我們相信,如果你開始在 SpringSource Application Platform 上開發基於 Spring 和 OSGi 的企業應用程式,與直接針對 OSGi 服務平臺進行開發相比(儘管程式設計和部署模型相同),你在使用企業庫時遇到的障礙會少得多,因為後者可能無法按照你在 OSGi 環境下期望的方式工作。
執行時好處
執行時好處源於這樣一個事實:OSGi 中的模組不僅僅是開發時的構造。它們在執行時真實存在,擁有自己的生命週期,並且可以在執行系統中進行檢查。
- 可以在執行時獲得關於已安裝模組及其連線的完整資訊——這是運維團隊以前從未有過的洞察級別。
你可以列出所有已安裝的 bundle 及其版本,檢視它們匯出和匯入的包,還可以檢視它們匯出和匯入的服務(以及提供這些服務和包的 bundle 的身份)。以前,運維團隊對執行中的應用程式的可見性僅限於 JEE 部署單元級別,OSGi 改變了這一切。(順便說一句,SpringSource Application Management Suite 提供了更多的洞察,但這屬於另一個話題)。- 隔離變更
由於可以獨立地安裝、解除安裝、更新和重新整理模組,透過將變更範圍限定在較小的單元(bundle),可以降低修改生產應用程式的風險。應用程式的其餘部分(其他 bundle)可以保持不變。是的,你可能有一個漫長的變更控制流程,這意味著實際執行變更並沒有更快,但至少你現在可以在更大程度上確定沒有引入任何其他意外差異。- 共享依賴項
OSGi 對版本控制的支援使得在平臺中一次安裝企業庫的可信版本並在應用程式之間共享成為可能。- 只使用你需要的伺服器設施
由於伺服器平臺本身以模組化方式構建在 OSGi 之上,你可以配置平臺只包含支援當前在其上執行的應用程式所需的那些服務。
非 OSGi 相關的好處
如果你對 OSGi 毫不在乎呢???SpringSource Application Platform 是否仍能帶來好處?
是的,確實如此。
我喜歡這樣看待 SpringSource Application Platform
首先,它是一個伺服器。一個輕量級、可配置且注重可維護性的伺服器(參見Rob 關於該平臺的原創文章)。它具有許多有用的功能,例如每個應用程式獨立的跟蹤和日誌檔案、死鎖檢測、故障檢測和轉儲處理、智慧執行緒池和工作竊取等。基於這些原因,它是部署 Web 應用程式的絕佳選擇。
其次,它是一個理解基於 Spring 應用程式的伺服器。Spring 整合是開箱即用的,部署器可以簡化打包和部署基於 Spring 的應用程式的過程——例如,無需為了配置 Spring 的 DispatcherServlet 而使用樣板式的 web.xml 檔案。
第三,也僅僅是第三,它為終端使用者應用程式提供 OSGi 支援,帶來了我上面已經概述的好處。