classloader簡(jiǎn)介

classloader簡(jiǎn)介

ClassLoader的具體作用就是將class文件加載到j(luò)vm虛擬機(jī)中去割粮,程序就可以正確運(yùn)行了筹吐。但是杨伙,jvm啟動(dòng)的時(shí)候,并不會(huì)一次性加載所有的class文件传藏,而是根據(jù)需要去動(dòng)態(tài)加載。
classloader 有兩種裝載class的方式 (時(shí)機(jī)):

  1. 隱式:運(yùn)行過(guò)程中彤守,碰到new方式生成對(duì)象時(shí)漩氨,隱式調(diào)用classLoader到JVM
  2. 顯式:通過(guò)class.forname()動(dòng)態(tài)加載

類加載器的樹(shù)狀組織結(jié)構(gòu)

Java 中的類加載器大致可以分成兩類,一類是系統(tǒng)提供的遗增,另外一類則是由 Java 應(yīng)用開(kāi)發(fā)人員編寫(xiě)的叫惊。系統(tǒng)提供
的類加載器主要有下面三個(gè):

-引導(dǎo)類加載器(Bootstrap Classloader):它用來(lái)加載 Java 的核心庫(kù),是用原生代碼來(lái)實(shí)現(xiàn)的做修,并不繼承自 java.lang.ClassLoader 霍狰。

-擴(kuò)展類加載器(Extensions Classloader):它用來(lái)加載 Java 的擴(kuò)展庫(kù)抡草。Java 虛擬機(jī)的實(shí)現(xiàn)會(huì)提供一個(gè)擴(kuò)展庫(kù)目錄。該類加載器在此目錄里面查找并加載 Java 類蔗坯。

-系統(tǒng)類加載器(System Classloader):它根據(jù) Java 應(yīng)用的類路徑(CLASSPATH)來(lái)加載 Java 類康震。一般來(lái)說(shuō),Java 應(yīng)用的類都是由它來(lái)完成加載的宾濒⊥榷蹋可以通過(guò) ClassLoader.getSystemClassLoader() 來(lái)獲取它。
除了系統(tǒng)提供的類加載器以外绘梦,開(kāi)發(fā)人員可以通過(guò)繼承 java.lang.ClassLoader 類的方式實(shí)現(xiàn)自己的類加載器橘忱,以滿足一些特殊的需求。
一個(gè)ClassLoader創(chuàng)建時(shí)如果沒(méi)有指定parent卸奉,那么它的parent默認(rèn)就是AppClassLoader钝诚。
每個(gè)Thread都有一個(gè)相關(guān)聯(lián)的ClassLoader,默認(rèn)是AppClassLoader榄棵。并且子線程默認(rèn)使用父線程的ClassLoader

除非子線程特別設(shè)置凝颇。

雙親委托

                              BootStrap Classloder
                                       |
                             Extensions Classloader
                                       |
                               System Classloader
                               /                \
                 Custom Classloader          Webapp Classloader

一個(gè)類加載器查找class和resource時(shí),是通過(guò)“委托模式”進(jìn)行的疹鳄,它首先判斷這個(gè)class是不是已經(jīng)加載成功拧略,如果沒(méi)有的話它并不是自己進(jìn)行查找,而是先通過(guò)父加載器瘪弓,然后遞歸下去垫蛆,直到Bootstrap ClassLoader,如果Bootstrap classloader找到了杠茬,直接返回月褥,如果沒(méi)有找到,則一級(jí)一級(jí)返回瓢喉,最后到達(dá)自身去查找這些對(duì)象宁赤。這種機(jī)制就叫做雙親委托

使用這種模型來(lái)組織類加載器之間的關(guān)系的好處: 主要是為了 安全性 ,避免用戶自己編寫(xiě)的類動(dòng)態(tài)替換 Java 的一些核心類栓票,比如 String决左,同時(shí)也避免了 重復(fù)加載 ,因?yàn)?JVM 中區(qū)分不同類走贪,不僅僅是根據(jù)類名佛猛,相同的 class 文件被不同的 ClassLoader 加載就是不同的兩個(gè)類,如果相互轉(zhuǎn)型的話會(huì)拋java.lang.ClassCaseException.

用序列描述一下:

  1. 一個(gè)AppClassLoader查找資源時(shí)坠狡,先看看緩存是否有继找,緩存有從緩存中獲取,否則委托給父加載器逃沿。
  2. 遞歸婴渡,重復(fù)第1部的操作幻锁。
  3. 如果ExtClassLoader也沒(méi)有加載過(guò),則由Bootstrap ClassLoader出面边臼,它首先查找緩存哄尔,如果沒(méi)有找到的
    話,就去找自己的規(guī)定的路徑下柠并,也就是 sun.mic.boot.class 下面的路徑岭接。找到就返回,沒(méi)有找到臼予,讓子加
    載器自己去找鸣戴。
  4. Bootstrap ClassLoader如果沒(méi)有查找成功,則ExtClassLoader自己在 java.ext.dirs 路徑中去查找瘟栖,查找成
    功就返回葵擎,查找不成功谅阿,再向下讓子加載器找半哟。
  5. ExtClassLoader查找不成功,AppClassLoader就自己查找签餐,在 java.class.path 路徑下查找寓涨。找到就返回。
    如果沒(méi)有找到就讓子類找氯檐,如果沒(méi)有子類會(huì)怎么樣戒良?拋出各種異常。

常見(jiàn)加載類錯(cuò)誤分析

ClassNotFoundExecption

ClassNotFoundExecption 異常是平常碰到的最多的冠摄。這個(gè)異常通常發(fā)生在顯示加載類的時(shí)候糯崎。
顯示加載一個(gè)類通常有:

-通過(guò)類 Class 中的 forName() 方法
-通過(guò)類 ClassLoader 中的 loadClass() 方法
-通過(guò)類 ClassLoader 中的 findSystemClass() 方法

出現(xiàn)這種錯(cuò)誤其實(shí)就是當(dāng) JVM 要加載指定文件的字節(jié)碼到內(nèi)存時(shí),并沒(méi)有找到這個(gè)文件對(duì)應(yīng)的字節(jié)碼河泳,也就是這個(gè)文件并不存在沃呢。解決方法就是檢查在當(dāng)前的 classpath 目錄下有沒(méi)有指定的文件。

NoClassDefFoundError

在JavaDoc中對(duì)NoClassDefFoundError的產(chǎn)生可能的情況就是使用new關(guān)鍵字拆挥、屬性引用某個(gè)類薄霜、繼承了某個(gè)接口或者類,以及方法的某個(gè)參數(shù)中引用了某個(gè)類纸兔,這時(shí)就會(huì)觸發(fā)JVM或者類加載器實(shí)例嘗試加載類型的定義惰瓜,但是該定義卻沒(méi)有找到,影響了執(zhí)行路徑汉矿。換句話說(shuō)崎坊,在編譯時(shí)這個(gè)類是能夠被找到的,但是在執(zhí)行時(shí)卻沒(méi)有找到洲拇。

解決這個(gè)錯(cuò)誤的方法就是確保每個(gè)類引用的類都在當(dāng)前的classpath下面奈揍。

ClassCastException

該錯(cuò)誤通常出現(xiàn)強(qiáng)制類型轉(zhuǎn)換時(shí)出現(xiàn)這個(gè)錯(cuò)誤痹届。

NoSuchMethodError

NoSuchMethodError代表這個(gè)類型確實(shí)存在,但是一個(gè)不正確的版本被加載了打月。

平臺(tái)類加載簡(jiǎn)介

我認(rèn)為有了上一節(jié)classloader的介紹后队腐,所謂的平臺(tái)的類加載原理其實(shí)就是classloader那部分內(nèi)容因?yàn)榻?jīng)常遇到j(luò)ar包沖突的問(wèn)題,小部分同事還經(jīng)常將jar包因?yàn)轭惣虞d不到或不對(duì)奏篙,嘗試性的將jar包放各種目錄柴淘,以提一下類加載是有先后順序的,有助于大家以后先定位問(wèn)題再解決問(wèn)題秘通,而不是嘗試解決后为严,還不清楚問(wèn)題原因的本質(zhì),避免將來(lái)重蹈覆轍肺稀。

平臺(tái)的類加載優(yōu)先級(jí)


lib/ > applib/ > app/applib/ > app/模塊/applib/ > ${HWORKDIR}/ > ${HWORKDIR}/app/

這里的模塊指的是${HWORKDIR}/etc/app.list中的模塊第股,一行一個(gè)模塊

至于weblib,其實(shí)它不是我們的類加載器指定的路徑话原,它真正被使用到的是webapp的lib/下通過(guò)軟連接引用的夕吻,由于webapp可能較多,所以用weblib一個(gè)公共存放管理的目錄可以很好的統(tǒng)一管理web類jar包

平臺(tái)自定義類加載器

 package com.xxx.loader;
import java.net.URL;
import java.net.URLClassLoader;
public class XxStandardClassLoader extends URLClassLoader {
    public XxStandardClassLoader(URL repositories[]) {    
      super(repositories);        
      }    
    public XxStandardClassLoader(URL repositories[], ClassLoader parent) {
       super(repositories, parent); 
    }    
}

每一個(gè)ATR服務(wù)解析成java對(duì)象時(shí)繁仁,都會(huì)創(chuàng)建其獨(dú)有的XxStandardClassLoader涉馅,也就是每一個(gè)ATR配置文件對(duì)應(yīng)的服務(wù),都有一個(gè)與其對(duì)應(yīng)的不同與其他服務(wù)的類加載器黄虱。這樣在每個(gè)線程執(zhí)行這些服務(wù)的Process方法之前稚矿,處理引擎負(fù)責(zé)將當(dāng)前線程的classloader替換為該服務(wù)的classloader,以便處理中的classloader為當(dāng)前服務(wù)的classloader捻浦,當(dāng)Process結(jié)束時(shí)晤揣,處理引擎又將classloader還原為之前的。這樣可以做到服務(wù)間的類隔離朱灿,再結(jié)合類加載的優(yōu)先順序昧识,還以做到同一個(gè)容器下,不同服務(wù)可以使用不同版本的類母剥,這種方式也可以解決類沖突帶來(lái)的問(wèn)題滞诺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市环疼,隨后出現(xiàn)的幾起案子习霹,更是在濱河造成了極大的恐慌,老刑警劉巖炫隶,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淋叶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伪阶,警方通過(guò)查閱死者的電腦和手機(jī)煞檩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)处嫌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人斟湃,你說(shuō)我怎么就攤上這事熏迹。” “怎么了凝赛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵注暗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我墓猎,道長(zhǎng)捆昏,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任毙沾,我火速辦了婚禮骗卜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘左胞。我一直安慰自己寇仓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布罩句。 她就那樣靜靜地躺著焚刺,像睡著了一般敛摘。 火紅的嫁衣襯著肌膚如雪门烂。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天兄淫,我揣著相機(jī)與錄音屯远,去河邊找鬼。 笑死捕虽,一個(gè)胖子當(dāng)著我的面吹牛慨丐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泄私,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼房揭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了晌端?” 一聲冷哼從身側(cè)響起捅暴,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咧纠,沒(méi)想到半個(gè)月后蓬痒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡漆羔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年梧奢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狱掂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亲轨,死狀恐怖趋惨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惦蚊,我是刑警寧澤希柿,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站养筒,受9級(jí)特大地震影響曾撤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晕粪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一挤悉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧巫湘,春花似錦装悲、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至阅嘶,卻和暖如春属瓣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讯柔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工抡蛙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人魂迄。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓粗截,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親捣炬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熊昌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • ClassLoader翻譯過(guò)來(lái)就是類加載器,普通的java開(kāi)發(fā)者其實(shí)用到的不多湿酸,但對(duì)于某些框架開(kāi)發(fā)者來(lái)說(shuō)卻非常常見(jiàn)...
    時(shí)待吾閱讀 1,078評(píng)論 0 1
  • 作者簡(jiǎn)介 原創(chuàng)微信公眾號(hào)郭霖 WeChat ID: guolin_blog 本篇是fank909的第四篇投稿稿械,詳細(xì)...
    木木00閱讀 1,612評(píng)論 1 14
  • 1选泻、classLoader 類加載器,將class文件加載到JVM虛擬機(jī)內(nèi)存中,使得程序可以運(yùn)行页眯。通常情況下梯捕,JV...
    helloWorld_1118閱讀 2,221評(píng)論 0 2
  • 本篇文章已授權(quán)微信公眾號(hào) guolin_blog (郭霖)獨(dú)家發(fā)布 ClassLoader翻譯過(guò)來(lái)就是類加載器,普...
    尼爾君閱讀 661評(píng)論 1 0
  • 你的心付出多少的愛(ài) 就會(huì)收獲多少的愛(ài) 當(dāng)心碎了的時(shí)侯 就再也感覺(jué)不到痛了 愛(ài)窝撵,也會(huì)不復(fù)存在
    小青金閱讀 391評(píng)論 4 3