婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 淺談Tomcat如何打破雙親委托機制

淺談Tomcat如何打破雙親委托機制

熱門標簽:烏海智能電話機器人 在百度地圖標注車輛 400電話申請方案 做外呼系統的公司違法嗎 威海人工外呼系統供應商 貴陽教育行業電話外呼系統 撫順移動400電話申請 藍點外呼系統 寧夏房產智能外呼系統要多少錢

我們經常會遇到ClassNotFound異常,表明JVM在嘗試加載某類時失敗了。

要解決這個異常,你得知道

  • 什么是類加載
  • JVM如何加載類
  • 為什么會出現ClassNotFound

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

JVM的類加載器

Java的類加載,就是把字節碼格式.class文件加載到JVM的方法區,并在JVM堆建立一個java.lang.Class對象實例,封裝Java類相關的數據和方法。

Class對象是什么?
可以理解成業務類的模板,JVM根據該模板創建具體業務類對象實例。

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

public abstract class ClassLoader {

    // 每個類加載器都有個父加載器
    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);
          }
        }
        // 若父加載器未加載成功,調用自己的findClass去加載
        if (c == null) {
            c = findClass(name);
        }
        
        return c;
    }
    
    protected Class<?> findClass(String name){
       // 1. 根據傳入的類名name,到在特定目錄下去尋找類文件,把.class文件讀入內存
          ...
          
       // 2. 調用defineClass將字節數組轉成Class對象
       return defineClass(buf, off, len);
    }
    
    // 將字節碼數組解析成一個Class對象,用native方法實現
    protected final Class<?> defineClass(byte[] b, int off, int len){
       ...
    }
}

JVM的類加載器是分層的父子關系,每個類加載器都持有一個parent字段指向父加載器。

  • defineClass 工具方法:調用native方法把Java類的字節碼解析成一個Class對象
  • findClass 就是找到 .class 文件,可能來自文件系統或網絡,找到后把 .class 文件讀到內存得到字節碼數組,然后調用defineClass方法得到Class對象

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

JDK的類加載器工作原理是一樣的,區別只是加載路徑不同,即findClass查找的路徑不同。
雙親委托機制是為保證一個Java類在JVM的唯一性。假如你手滑寫個與JRE核心類同名類,比如Object,雙親委托機制能保證加載的是JRE里的那個Object類,而不是你寫的Object。
因為AppClassLoader在加載你的Object類時,會委托給ExtClassLoader去加載,而ExtClassLoader又會委托給BootstrapClassLoader,BootstrapClassLoader發現自己已經加載過了Object類,會直接返回,不會去加載你的Object類。

類加載器的父子關系不是通過繼承來實現的,比如AppClassLoader并非ExtClassLoader的子類,只是AppClassLoader的parent指向ExtClassLoader對象。
所以若自定義類加載器,不是去繼承AppClassLoader,而是繼承ClassLoader抽象類,再重寫findClass和loadClass即可。
Tomcat就是通過自定義類加載器實現自己的類加載。
若你要打破雙親委托,也就只需重寫loadClass,因為loadClass的默認實現就是雙親委托機制。

Tomcat的類加載器

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

findClass

public Class<?> findClass(String name) throws ClassNotFoundException {
    ...
    
    Class<?> clazz = null;
    try {
            //1. 先在Web應用目錄下查找類 
            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應用本地目錄下查找要加載的類
  • 若未找到,交給父加載器查找,即AppClassLoader
  • 若父加載器也沒找到這個類,拋ClassNotFound

loadClass

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

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

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

        //2. 從系統類加載器的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. 嘗試用系統類加載器(也就是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的類加載器是否已經加載過這個類。
  • 若Tomcat類加載器尚未加載過該類,再看看系統類加載器是否加載過
  • 若都沒有,就讓ExtClassLoader加載,為防止Web應用自己的類覆蓋JRE的核心類
  • 因為Tomcat需打破雙親委托,假如Web應用里自定義了一個叫Object的類,若先加載該Object類,就會覆蓋JRE的Object類,所以Tomcat類加載器優先嘗試用ExtClassLoader去加載,因為ExtClassLoader會委托給BootstrapClassLoader去加載,BootstrapClassLoader發現自己已經加載了Object類,直接返回給Tomcat的類加載器,這樣Tomcat的類加載器就不會去加載Web應用下的Object類了,避免覆蓋JRE核心類。
  • 若ExtClassLoader加載失敗,即JRE無此類,則在本地Web應用目錄下查找并加載
  • 若本地目錄下無此類,說明不是Web應用自己定義的類,那么由系統類加載器去加載。這里請你注意,Web應用是通過Class.forName調用交給系統類加載器的,因為Class.forName的默認加載器就是系統類加載器。
  • 若上述加載過程都失敗,拋ClassNotFound

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

到此這篇關于淺談Tomcat如何打破雙親委托機制的文章就介紹到這了,更多相關Tomcat 雙親委托機制內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

標簽:周口 泰州 松原 那曲 銅川 慶陽 蕪湖 朝陽

巨人網絡通訊聲明:本文標題《淺談Tomcat如何打破雙親委托機制》,本文關鍵詞  淺談,Tomcat,如何,打破,雙親,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《淺談Tomcat如何打破雙親委托機制》相關的同類信息!
  • 本頁收集關于淺談Tomcat如何打破雙親委托機制的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    国产欧美一区二区三区在线老狼 | 国产精品亚洲第一区在线暖暖韩国| 精品国产一区二区三区av性色| 国产精品一区二区视频| 亚洲蜜臀av乱码久久精品蜜桃| 欧美日本一区二区三区| av日韩在线网站| 黑人巨大精品欧美黑白配亚洲| 一区二区成人在线| 亚洲国产成人一区二区三区| 91精品国产综合久久精品图片| 国产美女在线观看一区| 日本午夜一本久久久综合| 亚洲另类春色国产| 国产精品卡一卡二| 国产日产精品1区| 久久综合九色综合97婷婷| 欧美日韩在线免费视频| 91高清视频在线| 成人h版在线观看| 粉嫩高潮美女一区二区三区| 蜜臀精品一区二区三区在线观看 | 国产精品久久久久国产精品日日| 精品久久久久久久人人人人传媒| 欧美日韩一区 二区 三区 久久精品| 不卡一区二区在线| 高清成人免费视频| 国产精品123| 国产高清不卡一区| 国产乱人伦偷精品视频免下载| 麻豆国产精品官网| 久久精品久久99精品久久| 婷婷综合在线观看| 日韩在线一区二区三区| 青青国产91久久久久久| 久久精品av麻豆的观看方式| 国内精品在线播放| 国产一区二区在线观看免费| 国产激情视频一区二区三区欧美| 蜜乳av一区二区三区| 午夜精品久久久久久不卡8050| 亚洲精品你懂的| 午夜视频在线观看一区二区| 亚洲午夜久久久久久久久久久| 精品国产一区二区精华| 国产欧美精品一区二区色综合朱莉 | 北岛玲一区二区三区四区| fc2成人免费人成在线观看播放| 成人久久久精品乱码一区二区三区| 国产风韵犹存在线视精品| 91在线国内视频| 欧美性一二三区| 亚洲国产电影在线观看| 有坂深雪av一区二区精品| 夜夜嗨av一区二区三区中文字幕 | 国产亚洲精品bt天堂精选| 国产欧美日韩激情| 亚洲三级在线播放| 亚洲激情图片qvod| 久久99精品国产麻豆不卡| av亚洲精华国产精华| 欧美一区二区三区成人| 亚洲国产成人在线| 国产自产2019最新不卡| 99久久久无码国产精品| 欧美一三区三区四区免费在线看| 国产精品国产三级国产有无不卡 | 波多野结衣中文一区| 欧美性淫爽ww久久久久无| 2019国产精品| 亚洲欧洲国产专区| 亚洲精品少妇30p| 久久97超碰国产精品超碰| 95精品视频在线| 欧美日韩亚洲综合在线| 国产精品你懂的在线| 天天操天天干天天综合网| 国产精一区二区三区| 色偷偷成人一区二区三区91| 欧美电影免费观看高清完整版| 中文字幕日韩一区二区| 奇米精品一区二区三区四区| 国产精品羞羞答答xxdd| 欧美日韩国产乱码电影| 国产三级精品视频| 奇米一区二区三区| 色噜噜夜夜夜综合网| 欧美国产精品专区| 免费欧美在线视频| 91九色02白丝porn| 国产欧美综合在线观看第十页| 亚洲高清免费在线| 99精品视频一区二区三区| 欧美电影一区二区三区| 一区二区三区不卡视频在线观看 | 日欧美一区二区| 91豆麻精品91久久久久久| 国产亚洲精品福利| 国产在线不卡一区| 欧美亚洲高清一区二区三区不卡| 国产欧美日韩一区二区三区在线观看| 麻豆国产一区二区| 日韩三级在线免费观看| 天堂成人免费av电影一区| 99精品视频在线播放观看| **网站欧美大片在线观看| 国产成人h网站| 久久女同精品一区二区| 久久99最新地址| 精品理论电影在线观看 | 蜜桃免费网站一区二区三区| 51午夜精品国产| 日本网站在线观看一区二区三区| 日韩一区二区精品| 国产一区免费电影| 日本韩国欧美一区| 亚洲国产色一区| 884aa四虎影成人精品一区| 五月激情综合婷婷| 日韩免费一区二区三区在线播放| 蜜臀国产一区二区三区在线播放| 91精品国产欧美日韩| 午夜视频在线观看一区二区| 欧美吻胸吃奶大尺度电影| 亚洲精品一卡二卡| 91精品国产手机| 老司机精品视频导航| 久久久三级国产网站| 成人少妇影院yyyy| 一区二区视频在线| 欧洲亚洲国产日韩| 奇米777欧美一区二区| 91精品在线免费| 美女久久久精品| 精品噜噜噜噜久久久久久久久试看 | 国产午夜精品久久久久久久| 成人免费看黄yyy456| 日韩一卡二卡三卡四卡| 亚洲一区二区欧美| 自拍av一区二区三区| 91精品国产福利在线观看| 亚洲日本丝袜连裤袜办公室| 免费高清不卡av| 国产一区二区三区四区五区美女 | 亚洲午夜精品17c| 极品少妇xxxx偷拍精品少妇| 91精品国产综合久久香蕉麻豆| 成人欧美一区二区三区| 国产一区二区在线电影| 欧美精品777| 成人a区在线观看| 久久久午夜电影| 偷拍日韩校园综合在线| 99re成人精品视频| 亚洲一区二区av在线| 日韩亚洲欧美中文三级| 天天综合网天天综合色| 一区二区久久久久| 中文在线资源观看网站视频免费不卡| 天天综合网 天天综合色| 一本色道久久综合亚洲精品按摩| 日韩欧美亚洲一区二区| 轻轻草成人在线| 亚洲天堂中文字幕| 一本色道久久加勒比精品| 欧美激情一区在线观看| 国产suv精品一区二区6| 日韩不卡在线观看日韩不卡视频| 欧美年轻男男videosbes| 亚洲视频1区2区| 欧美日免费三级在线| 日韩黄色一级片| 91精品国模一区二区三区| 午夜视频在线观看一区| 在线观看精品一区| 高清国产一区二区三区| 樱花影视一区二区| 日本高清成人免费播放| 美女高潮久久久| 久久精品人人做人人爽人人| 成人午夜免费电影| 亚洲日本在线观看| 久久久99久久| 麻豆精品视频在线观看视频| 国产精品女同一区二区三区| 精品99999| 成人综合激情网| 亚洲精品v日韩精品| 国产精品一区三区| 久久成人免费电影| 欧美日韩国产综合视频在线观看| 亚洲色图欧美偷拍| 欧美一区二区三级| 韩日欧美一区二区三区| 免费观看成人av| 在线观看中文字幕不卡| 美女在线观看视频一区二区| 欧美日韩国产色站一区二区三区| 国产美女在线精品| 国产伦精品一区二区三区在线观看|