此计算机必须为委派而被信任_如何增强 ClassLoader 双亲委派模式 ?
雙親委派模式
JVM加載類的實(shí)現(xiàn)方式,我們稱為 雙親委托模型: 如果一個(gè)類加載器收到了類加載的請求,他首先不會自己去嘗試加載這個(gè)類,而是把這個(gè)請求委托給自己的父加載器,每一層的類加載器都是如此,因此所有的類加載請求最終都應(yīng)該傳送到頂層的Bootstrap ClassLoader中,只有當(dāng)父加載器反饋?zhàn)约簾o法完成加載請求時(shí),子加載器才會嘗試自己加載。
雙親委派模式問題
雙親委派模式存在的問題就是不太靈活,和類的繼承類似,只能繼承一個(gè)類。一個(gè) classloader 只能有一個(gè)父親 classloader。 比如有如下的場景,我們需要加載 N 個(gè) 插件,這些插件使用自己的classloader來保證類的隔離。應(yīng)用可以使用插件classloader 加載的類。其結(jié)構(gòu)如下:
這樣的問題就是 Plug-in 之間是從上往下是繼承的關(guān)系,但是每一個(gè) plug-in 對于 App 而言應(yīng)該是同級別的關(guān)系 ,plug-in 之間應(yīng)該可以相互依賴。 以上的模式顯然是無法做到的。
雙親委派增強(qiáng)模式
雙親委派增強(qiáng)模式滿足以下內(nèi)容:
- Plugin Class loader 加載的 jar 都是隔離的,每一個(gè)jar 使用 一個(gè) Plugin classloader 進(jìn)行加載。
- 每一個(gè) Plugin Class Loader 實(shí)例與其它的 實(shí)例 互為 雙親委派模式。 plugin 1 可以使用 2、3 加載的class,同理 2 也可以 1、2 加載的class。
- AppClassLoader 可以引用 所有 plugin classloader 加載的 class。但是 plugin classloder 不能使用 AppClassloader加載的class,為單向雙親委派模式。
Plugin 如何隔離?
plugin 隔離比較簡單,只要使用不同的 Plugin classloader 實(shí)例進(jìn)行加載就可以隔離。
Plugin 如何互為雙親委派?
每一個(gè) pluginclassloader實(shí)例 指定加載自己的jar,并且每一個(gè) pluginclassloader實(shí)例 可以獲取到其他的pluginclassloader實(shí)例,在加載class的時(shí)候遍歷所有的其它的classloader,如果加載成功加載完成,如果沒有加載成功,自己再進(jìn)行加載。這樣就形成了所有 plugin 互為雙親委派模式。
fat jar 如何避免plugin的依賴被其他pluginclassloader加載?
當(dāng)前打包的方式很多都是 fat jar 方式,自己的依賴 jar 也會打進(jìn)自己的jar中,如果兩個(gè) plugin 分別依賴了 a-0.1jar 和 a-0.2.jar 。 如果按照上面的加載方式,plug-in-1 classloader 可能會加載到 a-0.2.jar 中的class。這樣就出現(xiàn)了問題。
比較簡單處理方式,在打包的時(shí)候可以把class 文件名稱記錄在 MANIFEST.MF 中,依賴 jar 不進(jìn)行記錄 ,這樣每一個(gè)plugin classloader 對應(yīng)加載的那些類就可以解析出來。
plug-in-1 classloader 加載class 過程如下:
- 識別這個(gè)class 在 其它的 classloader 中是否支持加載,判斷的依據(jù)就是 classloader 解析的 class記錄是否存在此class ,如果存在就使用其他的 plug-in classloader 進(jìn)行加載。否則自己進(jìn)行加載。
因?yàn)橐蕾噅ar中 class 沒有進(jìn)行記錄,所以一直會使用自己的classloader進(jìn)行加載。
參考 SOFA-ark 的classloader 模塊 PluginClassLoader.java
總結(jié)
以上是生活随笔為你收集整理的此计算机必须为委派而被信任_如何增强 ClassLoader 双亲委派模式 ?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 伦巴时间步的动作要领_准军集结号,叶教官
- 下一篇: [js高手之路] 跟GhostWu一起封