校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識(shí)庫 > 淺談Tomcat如何打破雙親委托機(jī)制

淺談Tomcat如何打破雙親委托機(jī)制

熱門標(biāo)簽:烏海智能電話機(jī)器人 在百度地圖標(biāo)注車輛 400電話申請(qǐng)方案 做外呼系統(tǒng)的公司違法嗎 威海人工外呼系統(tǒng)供應(yīng)商 貴陽教育行業(yè)電話外呼系統(tǒng) 撫順移動(dòng)400電話申請(qǐng) 藍(lán)點(diǎn)外呼系統(tǒng) 寧夏房產(chǎn)智能外呼系統(tǒng)要多少錢

我們經(jīng)常會(huì)遇到ClassNotFound異常,表明JVM在嘗試加載某類時(shí)失敗了。

要解決這個(gè)異常,你得知道

  • 什么是類加載
  • JVM如何加載類
  • 為什么會(huì)出現(xiàn)ClassNotFound

想想Tomcat又是如何加載和管理Web應(yīng)用下的Servlet呢?
Tomcat正是通過Context組件來加載管理Web應(yīng)用的,所以今天我會(huì)詳細(xì)分析Tomcat的類加載機(jī)制。但在這之前,我們有必要預(yù)習(xí)一下JVM的類加載機(jī)制,我會(huì)先回答一下一開始拋出來的問題,接著再談?wù)凾omcat的類加載器如何打破Java的雙親委托機(jī)制。

JVM的類加載器

Java的類加載,就是把字節(jié)碼格式.class文件加載到JVM的方法區(qū),并在JVM堆建立一個(gè)java.lang.Class對(duì)象實(shí)例,封裝Java類相關(guān)的數(shù)據(jù)和方法。

Class對(duì)象是什么?
可以理解成業(yè)務(wù)類的模板,JVM根據(jù)該模板創(chuàng)建具體業(yè)務(wù)類對(duì)象實(shí)例。

JVM并非在啟動(dòng)時(shí)就把所有 .class 文件都加載一遍,而是程序在運(yùn)行過程中用到該類才去加載。
JVM類加載由類加載器完成,JDK提供一個(gè)抽象類ClassLoader:

public abstract class ClassLoader {

    // 每個(gè)類加載器都有個(gè)父加載器
    private final ClassLoader parent;
    
    public Class<?> loadClass(String name) {
  
        // 查找該類是否被加載過
        Class<?> c = findLoadedClass(name);
        
        // 若未被加載過
        if( c == null ){
          // 【遞歸】委托給父加載器加載
          if (parent != null) {
              c = parent.loadClass(name);
          } else {
              // 若父加載器為空,查找Bootstrap加載器是否加載過了
              c = findBootstrapClassOrNull(name);
          }
        }
        // 若父加載器未加載成功,調(diào)用自己的findClass去加載
        if (c == null) {
            c = findClass(name);
        }
        
        return c;
    }
    
    protected Class<?> findClass(String name){
       // 1. 根據(jù)傳入的類名name,到在特定目錄下去尋找類文件,把.class文件讀入內(nèi)存
          ...
          
       // 2. 調(diào)用defineClass將字節(jié)數(shù)組轉(zhuǎn)成Class對(duì)象
       return defineClass(buf, off, len);
    }
    
    // 將字節(jié)碼數(shù)組解析成一個(gè)Class對(duì)象,用native方法實(shí)現(xiàn)
    protected final Class<?> defineClass(byte[] b, int off, int len){
       ...
    }
}

JVM的類加載器是分層的父子關(guān)系,每個(gè)類加載器都持有一個(gè)parent字段指向父加載器。

  • defineClass 工具方法:調(diào)用native方法把Java類的字節(jié)碼解析成一個(gè)Class對(duì)象
  • findClass 就是找到 .class 文件,可能來自文件系統(tǒng)或網(wǎng)絡(luò),找到后把 .class 文件讀到內(nèi)存得到字節(jié)碼數(shù)組,然后調(diào)用defineClass方法得到Class對(duì)象

loadClass 首先檢查這個(gè)類是不是已經(jīng)被加載過了,如果加載過了直接返回,否則交給父加載器去加載。
這是個(gè)遞歸調(diào)用,即子加載器持有父加載器引用,當(dāng)一個(gè)類加載器需加載一個(gè)Java類時(shí),會(huì)先委托父加載器去加載,然后父加載器在自己加載路徑中搜索Java類,當(dāng)父加載器在自己的加載范圍內(nèi)找不到時(shí),才會(huì)交還給子加載器加載,這就是雙親委托機(jī)制。

JDK的類加載器工作原理是一樣的,區(qū)別只是加載路徑不同,即findClass查找的路徑不同。
雙親委托機(jī)制是為保證一個(gè)Java類在JVM的唯一性。假如你手滑寫個(gè)與JRE核心類同名類,比如Object,雙親委托機(jī)制能保證加載的是JRE里的那個(gè)Object類,而不是你寫的Object。
因?yàn)锳ppClassLoader在加載你的Object類時(shí),會(huì)委托給ExtClassLoader去加載,而ExtClassLoader又會(huì)委托給BootstrapClassLoader,BootstrapClassLoader發(fā)現(xiàn)自己已經(jīng)加載過了Object類,會(huì)直接返回,不會(huì)去加載你的Object類。

類加載器的父子關(guān)系不是通過繼承來實(shí)現(xiàn)的,比如AppClassLoader并非ExtClassLoader的子類,只是AppClassLoader的parent指向ExtClassLoader對(duì)象。
所以若自定義類加載器,不是去繼承AppClassLoader,而是繼承ClassLoader抽象類,再重寫findClass和loadClass即可。
Tomcat就是通過自定義類加載器實(shí)現(xiàn)自己的類加載。
若你要打破雙親委托,也就只需重寫loadClass,因?yàn)閘oadClass的默認(rèn)實(shí)現(xiàn)就是雙親委托機(jī)制。

Tomcat的類加載器

Tomcat的自定義類加載器WebAppClassLoader打破了雙親委托機(jī)制:
首先自己嘗試去加載某個(gè)類,如果找不到再委托給父類加載器,目的是優(yōu)先加載Web應(yīng)用自己定義的類。
只需重寫ClassLoader的兩個(gè)方法:

findClass

public Class<?> findClass(String name) throws ClassNotFoundException {
    ...
    
    Class<?> clazz = null;
    try {
            //1. 先在Web應(yīng)用目錄下查找類 
            clazz = findClassInternal(name);
    }  catch (RuntimeException e) {
           throw e;
       }
    
    if (clazz == null) {
    try {
            //2. 如果在本地目錄沒有找到,交給父加載器去查找
            clazz = super.findClass(name);
    }  catch (RuntimeException e) {
           throw e;
       }
    
    //3. 如果父類也沒找到,拋出ClassNotFoundException
    if (clazz == null) {
        throw new ClassNotFoundException(name);
     }

    return clazz;
}

工作流程

  • 先在Web應(yīng)用本地目錄下查找要加載的類
  • 若未找到,交給父加載器查找,即AppClassLoader
  • 若父加載器也沒找到這個(gè)類,拋ClassNotFound

loadClass

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {

    synchronized (getClassLoadingLock(name)) {
 
        Class<?> clazz = null;

        //1. 先在本地cache查找該類是否已經(jīng)加載過
        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }

        //2. 從系統(tǒng)類加載器的cache中查找是否加載過
        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }

        // 3. 嘗試用ExtClassLoader類加載器類加載,為什么?
        ClassLoader javaseLoader = getJavaseClassLoader();
        try {
            clazz = javaseLoader.loadClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return clazz;
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }

        // 4. 嘗試在本地目錄搜索class并加載
        try {
            clazz = findClass(name);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return clazz;
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }

        // 5. 嘗試用系統(tǒng)類加載器(也就是AppClassLoader)來加載
            try {
                clazz = Class.forName(name, false, parent);
                if (clazz != null) {
                    if (resolve)
                        resolveClass(clazz);
                    return clazz;
                }
            } catch (ClassNotFoundException e) {
                // Ignore
            }
       }
    
    //6. 上述過程都加載失敗,拋出異常
    throw new ClassNotFoundException(name);
}

工作流程

  • 先在本地Cache查找該類是否已加載過
  • 即Tomcat的類加載器是否已經(jīng)加載過這個(gè)類。
  • 若Tomcat類加載器尚未加載過該類,再看看系統(tǒng)類加載器是否加載過
  • 若都沒有,就讓ExtClassLoader加載,為防止Web應(yīng)用自己的類覆蓋JRE的核心類
  • 因?yàn)門omcat需打破雙親委托,假如Web應(yīng)用里自定義了一個(gè)叫Object的類,若先加載該Object類,就會(huì)覆蓋JRE的Object類,所以Tomcat類加載器優(yōu)先嘗試用ExtClassLoader去加載,因?yàn)镋xtClassLoader會(huì)委托給BootstrapClassLoader去加載,BootstrapClassLoader發(fā)現(xiàn)自己已經(jīng)加載了Object類,直接返回給Tomcat的類加載器,這樣Tomcat的類加載器就不會(huì)去加載Web應(yīng)用下的Object類了,避免覆蓋JRE核心類。
  • 若ExtClassLoader加載失敗,即JRE無此類,則在本地Web應(yīng)用目錄下查找并加載
  • 若本地目錄下無此類,說明不是Web應(yīng)用自己定義的類,那么由系統(tǒng)類加載器去加載。這里請(qǐng)你注意,Web應(yīng)用是通過Class.forName調(diào)用交給系統(tǒng)類加載器的,因?yàn)镃lass.forName的默認(rèn)加載器就是系統(tǒng)類加載器。
  • 若上述加載過程都失敗,拋ClassNotFound

可見 Tomcat 類加載器打破了雙親委托,沒有一上來就直接委托給父加載器,而是先在本地目錄下加載。
但為避免本地目錄類覆蓋JRE核心類,會(huì)先嘗試用ExtClassLoader加載。
那為何不先用AppClassLoader加載?
若這樣,就又變成雙親委托,這就是Tomcat類加載器的奧妙。

到此這篇關(guān)于淺談Tomcat如何打破雙親委托機(jī)制的文章就介紹到這了,更多相關(guān)Tomcat 雙親委托機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

標(biāo)簽:周口 泰州 松原 那曲 銅川 慶陽 蕪湖 朝陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《淺談Tomcat如何打破雙親委托機(jī)制》,本文關(guān)鍵詞  淺談,Tomcat,如何,打破,雙親,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《淺談Tomcat如何打破雙親委托機(jī)制》相關(guān)的同類信息!
  • 本頁收集關(guān)于淺談Tomcat如何打破雙親委托機(jī)制的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    欧美一级专区免费大片| 亚洲综合一区二区三区| 最新国产精品久久精品| 亚洲成av人在线观看| 成人av午夜影院| 欧美一级片免费看| 曰韩精品一区二区| av色综合久久天堂av综合| 久久女同性恋中文字幕| 亚洲第一主播视频| aaa国产一区| 久久久99免费| 狠狠色综合播放一区二区| 欧美区在线观看| 亚洲制服丝袜在线| 91丨porny丨中文| 国产欧美一区二区在线观看| 麻豆精品视频在线观看视频| 欧美在线免费视屏| 亚洲免费在线观看视频| 成人免费毛片aaaaa**| 2欧美一区二区三区在线观看视频| 亚洲一区影音先锋| 一本色道久久加勒比精品| **欧美大码日韩| av一区二区三区黑人| 国产亚洲精品中文字幕| 国产精品白丝jk白祙喷水网站| 91精品免费在线| 日韩av电影免费观看高清完整版在线观看| 色一情一乱一乱一91av| 亚洲女同ⅹxx女同tv| av不卡免费在线观看| 自拍偷拍亚洲激情| 色就色 综合激情| 亚洲国产欧美在线人成| 欧美性受xxxx黑人xyx性爽| 亚洲第一久久影院| 欧美福利视频导航| 免费观看成人鲁鲁鲁鲁鲁视频| 欧美一级夜夜爽| 国产精品自拍在线| 国产精品日韩成人| 色综合久久久久综合| 一区二区三区不卡视频| 欧美天堂一区二区三区| 午夜精品久久久久久久99水蜜桃 | 99re这里都是精品| 中文字幕一区二区三区av| 91亚洲精品乱码久久久久久蜜桃| 国产精品盗摄一区二区三区| 94-欧美-setu| 亚洲超碰精品一区二区| 欧美一级欧美一级在线播放| 极品瑜伽女神91| 国产精品色婷婷| 欧美主播一区二区三区美女| 丝袜美腿亚洲综合| 26uuu亚洲综合色| 色综合久久中文字幕综合网| 亚洲va欧美va人人爽| 欧美精品一区二区三区蜜桃 | 99久久99久久精品免费看蜜桃| 亚洲女人小视频在线观看| 91精品国产欧美一区二区18 | 久久女同性恋中文字幕| 99r国产精品| 九一九一国产精品| 亚洲另类一区二区| 日韩精品中文字幕一区| 成人av电影在线网| 日韩av一区二| 中文字幕在线不卡国产视频| 正在播放亚洲一区| 成人免费va视频| 丝袜美腿成人在线| 中文字幕一区二区三区四区不卡 | 99九九99九九九视频精品| 日日夜夜一区二区| 中文字幕亚洲视频| 26uuuu精品一区二区| 欧美日韩成人一区| 91同城在线观看| 国产综合色精品一区二区三区| 亚洲综合男人的天堂| 欧美韩日一区二区三区| 日韩一级高清毛片| 欧美探花视频资源| eeuss鲁片一区二区三区在线观看| 男女男精品视频网| 亚洲综合色成人| 亚洲欧洲色图综合| 久久精品人人做人人爽人人| 欧美日韩精品一区二区三区| aa级大片欧美| 成人av网站免费| 国内成人精品2018免费看| 三级亚洲高清视频| 亚洲在线一区二区三区| 亚洲欧洲日产国产综合网| 精品av久久707| 日韩三级视频在线看| 欧美美女黄视频| 日本高清视频一区二区| 97se亚洲国产综合自在线 | 色域天天综合网| 不卡视频一二三四| 成人的网站免费观看| 懂色av中文字幕一区二区三区| 国产一区不卡精品| 久久丁香综合五月国产三级网站| 日韩在线卡一卡二| 五月天国产精品| 午夜伦欧美伦电影理论片| 一区二区三区中文字幕精品精品 | av中文字幕一区| 成人激情开心网| 91香蕉视频mp4| 欧洲色大大久久| 欧美亚洲动漫精品| 欧美挠脚心视频网站| 欧美人成免费网站| 日韩一区二区影院| 久久久亚洲国产美女国产盗摄 | 一区二区三区四区视频精品免费| 成人免费小视频| 一区二区三区加勒比av| 一区二区不卡在线播放| 亚洲一级电影视频| 蜜桃一区二区三区在线| 国产精品伊人色| 成人aa视频在线观看| 色哟哟国产精品| 欧美肥大bbwbbw高潮| 欧美mv日韩mv| 国产欧美日韩三级| 亚洲精品高清视频在线观看| 亚洲成人免费影院| 久久精品国产精品青草| 成人高清视频免费观看| 欧美亚洲国产bt| 精品国产乱码91久久久久久网站| 国产女同互慰高潮91漫画| 亚洲另类在线一区| 另类中文字幕网| 91视频你懂的| 日韩精品专区在线影院重磅| 国产精品全国免费观看高清| 《视频一区视频二区| 天涯成人国产亚洲精品一区av| 国产在线精品一区二区不卡了| www.综合网.com| 欧美一区二区三区在线观看视频| 久久久www成人免费毛片麻豆| 亚洲黄色在线视频| 国产老女人精品毛片久久| 91国在线观看| 国产调教视频一区| 日韩国产欧美一区二区三区| 国产成人欧美日韩在线电影| 91传媒视频在线播放| 久久久噜噜噜久久人人看| 1024精品合集| 国产乱子轮精品视频| 欧美色倩网站大全免费| 国产日韩综合av| 男女性色大片免费观看一区二区 | 国内精品国产三级国产a久久| www.欧美亚洲| 精品免费日韩av| 一区二区三区精品视频在线| 国产精品一级二级三级| 欧美精品日日鲁夜夜添| 亚洲色图在线播放| 国产91富婆露脸刺激对白| 日韩欧美色综合| 亚洲妇女屁股眼交7| 不卡的电影网站| 久久久午夜电影| 久久精品国产久精国产| 91超碰这里只有精品国产| 日韩久久一区二区| 成人午夜av电影| 久久久久99精品一区| 久久精品久久久精品美女| 欧美三级日韩三级国产三级| 亚洲老妇xxxxxx| 99久久er热在这里只有精品15| 国产无人区一区二区三区| 精久久久久久久久久久| 欧美一二三区在线观看| 日韩国产精品大片| 欧美蜜桃一区二区三区| 亚洲成人精品影院| 欧美最猛黑人xxxxx猛交| 亚洲欧美日韩国产另类专区| 99这里只有久久精品视频| 日本一区二区成人在线| 成人福利视频网站| 中文av一区二区|