国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Ken Wu's Blog ? java類加載器體系結(jié)構(gòu)(含hotswap原理)

java類加載器體系結(jié)構(gòu)(含hotswap原理)

jvm classLoader architecture :

a, Bootstrap ClassLoader/啟動(dòng)類加載器
主要負(fù)責(zé)jdk_home/lib目錄下的核心 api 或 -Xbootclasspath 選項(xiàng)指定的jar包裝入工作.

b, Extension ClassLoader/擴(kuò)展類加載器
主要負(fù)責(zé)jdk_home/lib/ext目錄下的jar包或 -Djava.ext.dirs 指定目錄下的jar包裝入工作

c, System ClassLoader/系統(tǒng)類加載器
主要負(fù)責(zé)java -classpath/-Djava.class.path所指的目錄下的類與jar包裝入工作.

b, User Custom ClassLoader/用戶自定義類加載器(java.lang.ClassLoader的子類)
在程序運(yùn)行期間, 通過(guò)java.lang.ClassLoader的子類動(dòng)態(tài)加載class文件, 體現(xiàn)java動(dòng)態(tài)實(shí)時(shí)類裝入特性.

類加載器的特性:

1, 每個(gè)ClassLoader都維護(hù)了一份自己的名稱空間, 同一個(gè)名稱空間里不能出現(xiàn)兩個(gè)同名的類。
2, 為了實(shí)現(xiàn)java安全沙箱模型頂層的類加載器安全機(jī)制, java默認(rèn)采用了 ” 雙親委派的加載鏈 ” 結(jié)構(gòu).
如下圖:

Class Diagram:

類圖中, BootstrapClassLoader是一個(gè)單獨(dú)的java類, 其實(shí)在這里, 不應(yīng)該叫他是一個(gè)java類。
因?yàn)椋?它已經(jīng)完全不用java實(shí)現(xiàn)了。

它是在jvm啟動(dòng)時(shí), 就被構(gòu)造起來(lái)的, 負(fù)責(zé)java平臺(tái)核心庫(kù)。(具體上面已經(jīng)有介紹)

啟動(dòng)類加載實(shí)現(xiàn) (其實(shí)我們不用關(guān)心這塊, 但是有興趣的, 可以研究一下 ):
bootstrap classLoader 類加載原理探索

自定義類加載器加載一個(gè)類的步驟 :

ClassLoader 類加載邏輯分析, 以下邏輯是除 BootstrapClassLoader 外的類加載器加載流程:

// 檢查類是否已被裝載過(guò)Class c = findLoadedClass(name);if (c == null ) {// 指定類未被裝載過(guò)try {if (parent != null ) {// 如果父類加載器不為空, 則委派給父類加載c = parent.loadClass(name, false );} else {// 如果父類加載器為空, 則委派給啟動(dòng)類加載加載c = findBootstrapClass0(name);}} catch (ClassNotFoundException e) {// 啟動(dòng)類加載器或父類加載器拋出異常后, 當(dāng)前類加載器將其// 捕獲, 并通過(guò)findClass方法, 由自身加載c = findClass(name);}}

用Class.forName加載類
Class.forName使用的是被調(diào)用者的類加載器來(lái)加載類的.
這種特性, 證明了java類加載器中的名稱空間是唯一的, 不會(huì)相互干擾.
即在一般情況下, 保證同一個(gè)類中所關(guān)聯(lián)的其他類都是由當(dāng)前類的類加載器所加載的.

public static Class forName(String className)throws ClassNotFoundException {return forName0(className, true , ClassLoader.getCallerClassLoader());} /** Called after security checks have been made. */private static native Class forName0(String name, boolean initialize,ClassLoader loader)throws ClassNotFoundException;

上圖中 ClassLoader.getCallerClassLoader 就是得到調(diào)用當(dāng)前forName方法的類的類加載器

線程上下文類加載器
java默認(rèn)的線程上下文類加載器是 系統(tǒng)類加載器(AppClassLoader).

// Now create the class loader to use to launch the applicationtry {loader = AppClassLoader.getAppClassLoader(extcl);} catch (IOException e) {throw new InternalError("Could not create application class loader" );} // Also set the context class loader for the primordial thread.Thread.currentThread().setContextClassLoader(loader);

以上代碼摘自sun.misc.Launch的無(wú)參構(gòu)造函數(shù)Launch()。
使用線程上下文類加載器, 可以在執(zhí)行線程中, 拋棄雙親委派加載鏈模式, 使用線程上下文里的類加載器加載類.
典型的例子有, 通過(guò)線程上下文來(lái)加載第三方庫(kù)jndi實(shí)現(xiàn), 而不依賴于雙親委派.
大部分java app服務(wù)器(jboss, tomcat..)也是采用contextClassLoader來(lái)處理web服務(wù)。
還有一些采用 hotswap 特性的框架, 也使用了線程上下文類加載器, 比如 seasar (full stack framework in japenese).

線程上下文從根本解決了一般應(yīng)用不能違背雙親委派模式的問(wèn)題.
使java類加載體系顯得更靈活.

隨著多核時(shí)代的來(lái)臨, 相信多線程開(kāi)發(fā)將會(huì)越來(lái)越多地進(jìn)入程序員的實(shí)際編碼過(guò)程中. 因此,
在編寫(xiě)基礎(chǔ)設(shè)施時(shí), 通過(guò)使用線程上下文來(lái)加載類, 應(yīng)該是一個(gè)很好的選擇.

當(dāng)然, 好東西都有利弊. 使用線程上下文加載類, 也要注意, 保證多根需要通信的線程間的類加載器應(yīng)該是同一個(gè),
防止因?yàn)椴煌念惣虞d器, 導(dǎo)致類型轉(zhuǎn)換異常(ClassCastException).

自定義的類加載器實(shí)現(xiàn)
defineClass(String name, byte[] b, int off, int len,ProtectionDomain protectionDomain)
是java.lang.Classloader提供給開(kāi)發(fā)人員, 用來(lái)自定義加載class的接口.

使用該接口, 可以動(dòng)態(tài)的加載class文件.

例如,
在jdk中, URLClassLoader是配合findClass方法來(lái)使用defineClass, 可以從網(wǎng)絡(luò)或硬盤(pán)上加載class.

而使用類加載接口, 并加上自己的實(shí)現(xiàn)邏輯, 還可以定制出更多的高級(jí)特性.

比如,

一個(gè)簡(jiǎn)單的hot swap 類加載器實(shí)現(xiàn):

import java.io.File;import java.io.FileInputStream;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader; /*** 可以重新載入同名類的類加載器實(shí)現(xiàn)* * 放棄了雙親委派的加載鏈模式.* 需要外部維護(hù)重載后的類的成員變量狀態(tài).** @author ken.wu* @mail ken.wug@gmail.com* 2007-9-28 下午01:37:43*/public class HotSwapClassLoader extends URLClassLoader { public HotSwapClassLoader(URL[] urls) {super (urls);} public HotSwapClassLoader(URL[] urls, ClassLoader parent) {super (urls, parent);} public Class load(String name)throws ClassNotFoundException {return load(name, false );} public Class load(String name, boolean resolve)throws ClassNotFoundException {if ( null != super .findLoadedClass(name))return reload(name, resolve); Class clazz = super .findClass(name); if (resolve)super .resolveClass(clazz); return clazz;} public Class reload(String name, boolean resolve)throws ClassNotFoundException {return new HotSwapClassLoader( super .getURLs(), super .getParent()).load(name, resolve);}} public class A {private B b; public void setB(B b) {this .b = b;} public B getB() {return b;}} public class B {}

這個(gè)類的作用是可以重新載入同名的類, 但是, 為了實(shí)現(xiàn)hotswap, 老的對(duì)象狀態(tài)
需要通過(guò)其他方式拷貝到重載過(guò)的類生成的全新實(shí)例中來(lái)。(A類中的b實(shí)例)

而新實(shí)例所依賴的B類如果與老對(duì)象不是同一個(gè)類加載器加載的, 將會(huì)拋出類型轉(zhuǎn)換異常(ClassCastException).

為了解決這種問(wèn)題, HotSwapClassLoader自定義了load方法. 即當(dāng)前類是由自身classLoader加載的, 而內(nèi)部依賴的類還是老對(duì)象的classLoader加載的.

public class TestHotSwap {public static void main(String args[]) {A a = new A();B b = new B();a.setB(b); System.out.printf("A classLoader is %s n" , a.getClass().getClassLoader());System.out.printf("B classLoader is %s n" , b.getClass().getClassLoader());System.out.printf("A.b classLoader is %s n" ,   a.getB().getClass().getClassLoader()); HotSwapClassLoader c1 = new HotSwapClassLoader( new URL[]{ new URL( "file:\e:\test\")} , a.getClass().getClassLoader());Class clazz = c1.load(" test.hotswap.A ");Object aInstance = clazz.newInstance(); Method method1 = clazz.getMethod(" setB ", B.class);method1.invoke(aInstance, b); Method method2 = clazz.getMethod(" getB ", null);Object bInstance = method2.invoke(aInstance, null); System.out.printf(" reloaded A.b classLoader is %s n", bInstance.getClass().getClassLoader());}}

輸出

A classLoader is sun.misc.Launcher$AppClassLoader@19821f
B classLoader is sun.misc.Launcher$AppClassLoader@19821f
A.b classLoader is sun.misc.Launcher$AppClassLoader@19821f
reloaded A.b classLoader is sun.misc.Launcher$AppClassLoader@19821f

轉(zhuǎn)載請(qǐng)注明原文鏈接:http://kenwublog.com/structure-of-java-class-loader

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
類加載器不喜歡我,想我慢下來(lái)
ClassLoader(2)Boot、App、Ext、線程加載器
類加載器
深入探討 Java 類加載器
2017年百度騰訊等 校招高頻面試題
Java虛擬機(jī)-線程上下文類加載器
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服