karaf內嵌文件服務器,關于OSGI(Karaf) Classloader的幾點說明

1. Java ClassLoader

Java通過Classloader加載Class,Classloader之間相互隔離。隔離真正的意思是:不同的Classloader可以加載相同的class定義,并且被jvm認定為不同的class。很多人對隔離有誤解,認為不同的Classloader之間不能相互訪問,這其實并不準確。可以這么理解:Classloader只是一個普通的Java類,加載的class集合是它的一個成員變量。如果一個Classloader中維護了另一個Classloader的引用,自然可以通過接口調用查找并使用另一個Classloader加載的類,雙親委派使用的正式這種機制。

雙親委派這名字乍一聽好像是說你有父親、母親兩個Classloader,你可以委派他們兩個先去加載class,他們處理不了的你再處理。如果真這么理解就全錯了。首先,他們不是兩個,可能是n個;其次,他們不是你的父母,他們是整個jvm共享的Classloader;第三,他們誰的父母都不是,因為你和他們沒有血緣(別人也沒有),你不是雙親Classloader的子類。

雙親委派的英文為parent delegation,指的是每個Classloader都有一個getParent方法獲取上一級的Classloader。查找類時,先調用parent Classloader查找,如果找不到在用自身的Classloader查找。層級關系如下:

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

parent delegation

雙親委派實際上只是引用關系,上述bootrasp、extension、application Classloader之間關系均屬此類。再來看另外一張圖:

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

自定義Classloader

bootrasp、extension、application Classloader在jvm中只有一個實例,多個用戶自定義的Classloader共享此實例,完成公共部分加載。

2. OSGI Classloader

在OSGI中,每一個Bundle有一個單獨的Classloader實例。更具體點,BundleWiringImpl中定義了一個BundleClassLoader,每當加載一個bundle時,框架創建一個BundleClassLoader實例負責該bundle相關class的加載工作。

BundleClassLoader的加載順序如下:

如class在 java.* package中,委托Bootstrap Classloader處理;

如class定義在 OSGi 框架中啟動委托列表(org.osgi.framework.bootdelegation)中,則將加載請求委托給Bootstrap Classloader處理;

如class在 Import-Package 定義的package中,則框架找到導出此package的 Bundle 的 Class Loader,交其處理 。

如class屬于在 Require-Bundle 中定義的 Bundle,則框架找到導出此package的Bundle的ClassLoader,交其處理。

Bundle 搜索自己的類資源 ( 包括 Bundle-Classpath 里面定義的類路徑和屬于 Bundle 的 Fragment 的類資源);

若類在 DynamicImport-Package 中定義,則開始嘗試在運行環境中尋找符合條件的 Bundle 。

Bundle之間隔離,但如果存在import關系又可以委托給相應export的classloader處理。實現上無非是維護了多個import bundle的Classloader,查找時調用其find方法實現。

需要注意的是:查找時優先查找Import-Package、Require-Bundle中的類,隨后才是查找Bundle自己的類。這里又引入另外一個疑問,Embed-Dependency使用問題。

簡單來說,如果一個Bunlde 需要使用protobuf-java.jar,有如下兩種使用方式:

普通的dependency方式使用,如下圖的Component C的使用方式。

Embed-dependency方式使用,如下圖的ComponentA、ComponentB,此時將protobuf-java做為Bundle自身的一部分使用。

14b40b570043?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

embed-dependency

按類加載的順序,如果先加載Import-Package隨后加載自身的Class,在外部存在protobuf-java,又有內嵌的protobuf-java時,如何做到使用自己的而非外部的呢?答案是在Embed-dependency中的jar并不會出現在Import-Package中。

最后再來講一下,為什么每個bundle需要分配單獨的Classloader,解決什么問題。在我看來,最主要的原因有如下兩個:

定制導出類。非osgi環境下,所有package中的java類都將被導出,無法限定哪些只能jar內使用,哪些是需要export出去的。存在各種誤用,耦合使用情況。

多版本控制。非osgi環境下,一個jvm對于一個類只允許存在一個版本。osgi中每個bundle是獨立開發演進的,可能出現同時存在多個版本。

3. 參考資料

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/529293.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/529293.shtml
英文地址,請注明出處:http://en.pswp.cn/news/529293.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

聲明變量的三種方式

聲明變量的三種方式 先聲明,再賦值:【常用】 數據類型 變量名; 變量名 值; 例: int b; b 5;聲明并賦值:【常用】 數據類型 變量名 值; 例: int a 5;多個類型的變量的聲明和賦值:…

常用idea快捷鍵

常用idea快捷鍵 常用 CtrlF12,可以顯示當前文件的結構 CtrlN,可以快速打開類 CtrlShiftN,可以快速打開文件 AltInsert,可以生成構造器/Getter/Setter等 AltEnter,導入包,自動修正 CtrlAltL,格…

char類型自動轉換成int類型

char類型自動轉換成int類型 char c1 65;int i1 c11;// 此處int類型范圍比char大 “1”默認為int 所以char類型自動提升為int類型System.out.println(i1);//此處結果為66

java局部變量簡述

java局部變量簡述 特點描述作用范圍離當前變量最近的大括號({})以內重名問題重合的作用范圍不能重名定義位置方法中if (a>10) {int c 20;System.out.println(c);}else {int c30;System.out.println(c);}此處c的作用范圍未重合,此處程序成…

eclipse debug(程序調試)單步執行 簡述

eclipse debug(程序調試)單步執行 簡述 1.在需要程序停止的地方 雙擊打一個斷點 2.右鍵以debug模式執行(有個蟲子標志的選項) 3.單步執行 觀察變量的變化 如圖所示: debug常見問題: 1.Variables(變量區…

方法中的參數,形參(形式參數)和實參(實際參數)簡述

方法中的參數,形參(形式參數)和實參(實際參數)簡述 形參(形式參數):表示在定義的方法的時候書寫的參數,形參規定了參數的個數、類型、順序 形參相當于局部變量的聲明&…

微信小程序~如何設置頁面的背景色

微信小程序~如何設置頁面的背景色 眾所周知,微信小程序每個頁面由.json,.scss,.ts,.wxml這四個文件組成。 有的小伙伴會發現,需要給頁面加背景色的時候,只需在此頁面的.scss文件中寫個page{background-colo…

return中斷方法和Unreachable code(永遠達不到的代碼)

return中斷方法和Unreachable code(永遠達不到的代碼) 1.下面這段代碼因為for循環是個死循環,System.out.println(); 執行不到編輯器會報錯Unreachable code(永遠達不到的代碼) public static void main(String[] ar…

java 中for循環中重復定義的變量 為什么不報錯?

java 中for循環中重復定義的變量 為什么不報錯&#xff1f; public class Test1 {public static void main(String[] args) {int[] arr {1,2,3,4,5};for (int i 0; i < arr.length; i) {int j 1;}} }此處變量 j 所作用的范圍為其所在的大括號&#xff08; { } &#xff…

Java JDK 自帶排序(Arrays.sort(數組名))與自行編寫的降序

JDK 自帶排序&#xff08;Arrays.sort(數組名)&#xff09;與自行編寫的降序 jdk 自帶的排序 Arrays.sort(數組名) 只能進行升序排列 可以與自己寫的降序 配合使用 import java.util.Arrays;public class Test1 {//jdk 自帶升序public static void m1(int [] arr1) {Arrays.sor…

javaee 中遇到的jdk自帶的異常(Exception)

javaee 中遇到的異常&#xff08;Exception&#xff09; 如果輸入了類型不匹配的數據&#xff0c;則會報InputMismathException(輸入不匹配異常) 如果訪問超過數組范圍的下標將會報數組下標越界異常&#xff1a;ArrayIndexOutOfBoundsException ( 數組越界異常) 在多態的向下轉…

實例變量和局部變量區別

實例變量和局部變量區別 實例變量局部變量定義位置定義在類中定義在方法中作用范圍變量所在的整個類中離變量最近的大括號中默認值有默認值&#xff0c;與數組相同無默認值&#xff0c;必須初始化關于重名可以與局部變量重名&#xff0c;就近原則使用重合的作用范圍&#xff0…

java this關鍵字表示當前對象,可以訪問屬性、方法、構造方法

this關鍵字的三種訪問方式&#xff1a;屬性、方法、構造方法 1.訪問屬性 為了命名的規范&#xff0c;利用this關鍵字區分了屬性與局部變量 public class Persion {String name;char sex;int age ;String hobby;int height;int weight;public Persion(String name,char sex ,in…

Java 訪問權限修飾符簡述

訪問權限修飾符簡述 1.類的訪問修飾符 public 最大訪問權限&#xff0c;本項目中的任何位置都可以訪問 默認不寫 &#xff1a;包級別的訪問權限&#xff0c;智能在同包中訪問 package com.qfedu.test2;//public修飾的類 public class A {public static void main(String[] arg…

java 靜態與非靜態之間的訪問規則簡述

java 靜態與非靜態之間的訪問規則簡述 1.靜態與靜態之間直接訪問 2.非靜態&#xff08;實例級別&#xff09;訪問靜態直接訪問 3.靜態訪問非靜態&#xff08;實例級別&#xff09;&#xff0c;必須先創建對象再訪問 package com.qfedu.test7; /*** 靜態和非靜態訪問規則&#x…

java super關鍵字簡述

java super關鍵字簡述 super關鍵字訪問父類屬性&#xff0c;訪問權限必須是允許的super關鍵字訪問父類屬性&#xff0c;訪問權限必須是允許的當創建子類對象時&#xff0c;默認調用父類的無參構造方法&#xff0c;除非顯式調用父類的有參構造方法&#xff0c;也就是說**子類創建…

java 雙等號(==) 與equals方法的使用區別

java 雙等號&#xff08;&#xff09; 與equals方法的區別 用于比較基本數據類型時&#xff0c;比較的是值用于比較引用數據類型時&#xff0c;比較的是地址equals方法在Object類中比較的也是地址&#xff0c;因為在低層也是使用進行比較String類調用equals方法比較的內容&…

java中的 31 和左移右移的關系簡述

java中的 31 和左移右移的關系簡述 任何數乘以31 等于 這個數左移 五位 減去這個數 ? n * 31 (n << 5) - n “ << ” 左移幾位 表示乘以2的幾次方 “ >> ” 右移幾位 表示除以2的幾次方 package com.qfedu.test3; /*** 任何數乘以31 等于 這個數左移 五位 …

c++ char* 改變長度重新賦值_[C/C++] 2 :分析下列代碼有什么問題?

題目分析下面代碼有什么問題&#xff1f;void test2() { char string[10], str1[10]; int i; for(i0; i<10; i) { str1 a; } strcpy( string, str1 ); } 解答代碼無法通過編譯。因為數組名str1為 char *const類型的右值類型&#xff0c;根本不能賦值。即使想對數組的第…

Java final 關鍵字簡述

final 關鍵字簡述 final:最終 1.final 修飾類 final 修飾的類不能被繼承 /*** final修飾的類 不能被繼承* author **/ public final class A { } //不能被繼承,此處報錯 //class B extends A{ // //}2.final修飾方法 final 修飾的方法不能被重寫 /*** final 修飾的方法 不能被…