從一個場景談起:?代碼里面用到Thread臨時改變ContextClassLoader,?加載類之后癞谒,再設(shè)置回來的例子。所以研究一下ClassLoader.
基礎(chǔ):?
三個ClassLoader:? Bootstrap, Ext,App.?
bootstrap用來加載java核心類著蛙,都放jre/lib里面胰柑;Ext用來加載擴(kuò)展類沙咏,在ext文件夾里面食茎;App用來加載classpath下面的類。這正好可以和配置java環(huán)境的時候的路徑配置對應(yīng)稀颁。
key1:?三者沒有物理上的父子關(guān)系芬失,只是邏輯上的。也就是parent只是classLoader的一個字段匾灶,?是設(shè)置的棱烂。而bootstrap都不是ext邏輯上的parent,只是功能上的阶女。app和ext設(shè)置parent構(gòu)造函數(shù)里面颊糜,而調(diào)用(傳入parent)在Launcher里面。
key2:?類關(guān)系
app,ext ----->UrlClassLoader------->secureClassLoader---->classLoader,?各個環(huán)節(jié)的作用根據(jù)名字可以猜出來秃踩,具體就要看代碼了衬鱼。而app和ext都是Laucher的內(nèi)部類。作為啟動最主要的內(nèi)容憔杨。
key3: Bootstrap是c++寫的鸟赫,jvm的一部分,所以在jdk里面沒有消别。
有趣的點:
key1: Thread里面有個字段ContextClassLoader,?用來設(shè)置線程中的classLoader.?這里就有一個疑問了:?有啥用抛蚤??當(dāng)前可以用上面那個場景回答,當(dāng)前線程加載一下自己定義的類妖啥。
使用:
key1: classLoader里面已經(jīng)寫了,?自定義classLoader不要覆寫loadClass对碌,?覆寫findClass荆虱;?不過并沒有強(qiáng)制,也就是loadClass上面并沒有什么final朽们。?這樣保證自定義classLoader依舊遵循雙親委派(為啥叫雙親呢怀读,?估計是parent翻譯,并不是真的有兩個)骑脱〔思希可以看一下loadClass的源碼,很容易理解叁丧,先是緩存查找啤誊,找不到就父親岳瞭,沒有父親就bootstrap,最后findClass. findClass定義的就是查找類的方法蚊锹。
key2: deineClass將二進(jìn)制文件轉(zhuǎn)成java?類瞳筏。
遺留的點:?
spring的類加載器。?貌似是自定義的牡昆。