Springboot Application 集成 OSGI 框架開發

Java 類加載器

啓動類加載器 (Bootstrap ClassLoader)

是 Java 類加載層次中最頂層的類加載器,負責加載 JDK 中的核心類庫,如:rt.jar、resources.jar、charsets.jar 等

擴展類加載器(Extension ClassLoader)

負責加載 Java 的擴展類庫,默認加載 JAVA_HOME/jre/lib/ext/目下的所有 jar

應用類加載器(Application ClassLoader)

負責加載應用程序 classpath 目錄下的所有 jar 和 class 文件。

ClassLoader 使用的是雙親委託模型來搜索類的,每個 ClassLoader 實例都有一個父類加載器的引用(不是繼承的關係,是一個包含的關係),虛擬機內置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器,但可以用作其它 ClassLoader 實例的的父類加載器。當一個 ClassLoader 實例需要加載某個類時,它會試圖親自搜索某個類之前,先把這個任務委託給它的父類加載器,這個過程是由上至下依次檢查的,首先由最頂層的類加載器 Bootstrap ClassLoader 試圖加載,如果沒加載到,則把任務轉交給 Extension ClassLoader 試圖加載,如果也沒加載到,則轉交給 App ClassLoader進行加載,如果它也沒有加載得到的話,則返回給委託的發起者,由它到指定的文件系統或網絡等 URL 中加載該類。如果它們都沒有加載到這個類時,則拋出 ClassNotFoundException 異常。否則將這個找到的類生成一個類的定義,並將它加載到內存當中,最後返回這個類在內存中的 Class 實例對象。

判別兩個類是否相同,除了是相同的 class 字節碼,還必須由同一類加載器加載。比如類 Example,javac 編譯之後生成字節碼文件 Example.class,ClassLoaderA 和 ClassLoaderB 這兩個類加載器並讀取了 Example.class 文件,並分別定義出了 java.lang.Class 實例來表示這個類,對於 JVM 來說,它們是兩個不同的實例對象,但它們確實是同一份字節碼文件,如果試圖將這個 Class 實例生成具體的對象進行轉換時,就會拋運行時異常 java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.Class

OSGI 類加載器

OSGI 類加載器並不遵循 Java 的雙親委派模型,OSGi 爲每個 bundle 提供一個類加載器,該加載器能夠加載 bundle 內部的類和資源,bundle 之間的交互是從一個 bundle 類加載器委託到另一個 bundle 類加載器,所有 bundle 都有一個父類加載器。

Fragment bundle 是一種特殊的 bundle,不是獨立的 bundle,必須依附於其他 bundle 來使用。通過 Fragment-Host 來指定宿主 bundle,同時也可以通過這種方式使用宿主的類加載器。

圖 1.OSGI 類加載器

image

OSGI 框架根據 Bundle 的 MANIFEST.MF 文件中描述的數據信息進行解析處理 Bundle 間的依賴關係。Fragment Bundle 的宿主 bundle 的檢查在 bundle 解析之前已經完成,所以 Fragement Bundle 可以獲取到宿主 bundle 的加載器信息。

Equinox OSGI ServletBridge 實現原理及源碼解析

BridgeServlet 與 OSGI 容器

Equinox 提供了 servletbridge.jar 將 OSGI framework 和 servlet container 橋接起來,並且提供了一系列的 bundle 可以將 Equinox OSGI 應用嵌入到現有的 web 服務器中(eg. Tomcat)。servletbridge.jar 包含如下兩個文件 (package: org.eclipse.equinox.servletbridge)

BridgeServlet – 負責請求處理

FrameworkLauncher – 負責 OSGI bundle 啓動管理

Web 工程被加載到 web 容器中,比如 Tomcat,容器讀取 web 工程 WEB-INF 目錄下的 web.xml 文件,通過 servlet mapping 指定相應的類處理請求......

https://www.ibm.com/developerworks/cn/java/j-springboot-application-integrated-osgi-framework-development/index.html

總結

本文從 Java 類加載器說起,探討了 OSGI 的類加載器原理並對 Equinox 中的 Servletbridge 原理實現進行了詳細的研究,同時擴展到使用這一原理如何在 Spring boot 應用中嵌入 OSGI 開發和 Spring boot 應用如何與 OSGI 插件之間進行相互調用。使用一個例子來對這一系列的使用做了進一步的講解。並對它的實現方法做了進一步的探討,這些探討對於將 OSGI 應用嵌入到任何其他的系統中是一個啓發和幫助,希望有興趣的讀者可以做進一步的瞭解和實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章