本文為《你好,OSGi》系列第三部分。前文介紹 OSGi 基礎與 Bundle 使用,本篇闡述依賴管理核心:Bundle 可視域概念。
OSGi 允許將應用拆分多模組並管理相依性。Bundle 內類別預設僅對內部可見,對外不可見;內部遵循 Java 一般規範。欲從一 Bundle 存取另一 Bundle 類別,須將來源 Bundle 套件導出,再導入目標 Bundle。
建立 com.javaworld.sample.HelloService Bundle 導出套件:
com.javaworld.sample.service.HelloService 介面(代碼清單 3)HelloServiceImpl(代碼清單 4)com.javaworld.sample.service(代碼清單 5)Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloService Plug-in
Bundle-SymbolicName: com.javaworld.sample.HelloService
Bundle-Version: 1.0.0
Bundle-Vendor: JavaWORLD
Bundle-Localization: plugin
Export-Package: com.javaworld.sample.service
Import-Package: org.osgi.framework;version="1.3.0"
關鍵:Export-Package 告知容器外部可存取該套件類別。示範僅導出介面 HelloService,隱藏實作 HelloServiceImpl(內部類)。
將導出套件導入 HelloWorld Bundle:
com.javaworld.sample.service(代碼清單 6)Import-Package: com.javaworld.sample.service,
org.osgi.framework;version="1.3.0"
Import-Package 為逗號分隔套件清單。org.osgi.framework 含 OSGi 框架類別(如 BundleContext、BundleActivator)。
Activator.java 可見現可存取 HelloService 介面,但不可見 HelloServiceImpl 實作類編譯期可存取 HelloServiceImpl,但在 OSGi 容器運行拋出異常。容器如何隱藏 JAR 內部分類別?
OSGi 容器為每個 Bundle 建立獨立類載入器,管理類別可見性。每個 Bundle 可存取:
java.* 開頭套件com.javaworld.sample.service)Bundle 級可視域為 OSGi 強大功能:可安全更新 HelloServiceImpl 無須擔心依賴代碼受損。