五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動(dòng)態(tài)

Tomcat的類加載機(jī)制流程及源碼解析

發(fā)布日期:2021-12-13 15:38 | 文章來(lái)源:gibhub

在前面 Java虛擬機(jī):對(duì)象創(chuàng)建過(guò)程與類加載機(jī)制、雙親委派模型 文章中,我們介紹了 JVM 的類加載機(jī)制以及雙親委派模型,雙親委派模型的類加載過(guò)程主要分為以下幾個(gè)步驟:

(1)初始化 ClassLoader 時(shí)需要指定自己的 parent 是誰(shuí)

(2)先檢查類是否已經(jīng)被加載過(guò),如果類已經(jīng)被加載了,直接返回

(3)若沒(méi)有加載則調(diào)用父加載器 parent 的 loadClass() 方法進(jìn)行加載

(4)若父加載器為空則默認(rèn)使用啟動(dòng)類加載器 bootstrap ClassLoader 進(jìn)行加載

(5)如果父類加載失敗,拋出 ClassNotFoundException 異常后,再調(diào)用自己的 findClass() 方法進(jìn)行加載。

前面文章也提到,如果想要破壞這種機(jī)制,那么就自定義一個(gè)類加載器(繼承自 ClassLoader),并重寫(xiě)其中的 loadClass() 方法,使其不進(jìn)行雙親委派即可。最經(jīng)典例子就是 Tomcat 容器的類加載機(jī)制了,它實(shí)現(xiàn)了自己的類加載器 WebApp ClassLoader,并且打破了雙親委派模型,在每個(gè)應(yīng)用在部署后,都會(huì)創(chuàng)建一個(gè)唯一的類加載器。

1、Tomcat 的類加載器結(jié)構(gòu)圖:

(1)Common ClassLoader:加載 common.loader 屬性下的 jar,一般是 CATALINA_HOME/lib 目錄下,主要是 tomcat 使用以及應(yīng)用通用的一些類

(2)Catalina ClassLoader:加載 server.loader 屬性下的 jar,默認(rèn)未配置路徑,返回其父加載器即 Common ClassLoader,主要是加載服務(wù)器內(nèi)部可⻅類,這些類應(yīng)⽤程序不能訪問(wèn);

(3)Shared Classloader:加載 share.loader 屬性下的jar,默認(rèn)未配置路徑,返回其父加載器即 Common ClassLoader,主要是加載應(yīng)⽤程序共享類,這些類對(duì) Tomcat 自己不可見(jiàn);

只有指定了 tomcat/conf/catalina.properties 配置文件的 server.loader 和 share.loader 項(xiàng)后,才會(huì)真正建立 Catalina ClassLoader 和 Shared ClassLoader 的實(shí)例,否則在用到這兩個(gè)類加載器的地方都會(huì)用 Common ClassLoader 的實(shí)例代替,而默認(rèn)的配置文件中是沒(méi)有設(shè)置這兩個(gè) loader 項(xiàng)的

(4)WebApp ClassLoader:Tomcat 可以存在多個(gè) WebApp ClassLoader 實(shí)例,每個(gè)應(yīng)⽤程序都會(huì)有⼀個(gè)獨(dú)⼀⽆⼆的 WebApp ClassLoader,⽤來(lái)加載本應(yīng)⽤程序 /WEB-INF/classes 和 /WEB-INF/lib 下的類。

2、Tomcat 的類加載流程說(shuō)明:

當(dāng) Tomcat 使用 WebAppClassLoader 進(jìn)行類加載時(shí),具體過(guò)程如下:

(1)先在本地 cache 緩存中查找該類是否已經(jīng)加載過(guò),看看 Tomcat 有沒(méi)有加載過(guò)這個(gè)類

(2)如果 Tomcat 沒(méi)有加載過(guò)這個(gè)類,則從系統(tǒng)類加載器的 cache 緩存中查找是否加載過(guò)

(3)如果沒(méi)有,則使用 ExtClassLoader 類加載器類加載,重點(diǎn)來(lái)了,Tomcat 的 WebAppClassLoader 并沒(méi)有先使用 AppClassLoader 來(lái)加載類,而是直接使用了 ExtClassLoader 來(lái)加載類。不過(guò) ExtClassLoader 依然遵循雙親委派,它會(huì)使用 Bootstrap ClassLoader 來(lái)對(duì)類進(jìn)行加載,保證了 Jre 里面的核心類不會(huì)被重復(fù)加載。

比如在 Web 中加載一個(gè) Object 類。WebAppClassLoader → ExtClassLoader → Bootstrap ClassLoader,這個(gè)加載鏈,就保證了 Object 不會(huì)被重復(fù)加載。

(4)如果沒(méi)有加載成功,WebAppClassLoader 就會(huì)調(diào)用自己的 findClass() 方法由自己來(lái)對(duì)類進(jìn)行加載,先在 WEB-INF/classes 中加載,再?gòu)?WEB-INF/lib 中加載。

(5)如果仍然未加載成功,WebAppclassLoader 會(huì)委派給 SharedClassLoader,SharedClassLoad 再委派給 CommonClassLoader,CommonClassLoader 委派給 AppClassLoader,直到最終委派給 BootstrapClassLoader,最后再一層一層地在自己目錄下對(duì)類進(jìn)行加載。

(6)都沒(méi)有加載成功的話,拋出異常。

3、源碼解析:

(1)WebAppClassLoader 的 loadClass() 方法源碼:

WebappClassLoader 應(yīng)用類加載器的 loadClass 在他的父類 WebappClassLoaderBase 中

public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
        Class<?> clazz = null;
        //1. 先在本地cache查找該類是否已經(jīng)加載過(guò)
        clazz = findLoadedClass0(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }
        //2. 從系統(tǒng)類加載器的cache中查找是否加載過(guò)
        clazz = findLoadedClass(name);
        if (clazz != null) {
            if (resolve)
                resolveClass(clazz);
            return clazz;
        }
        // 3. 嘗試用ExtClassLoader類加載器類加載(ExtClassLoader 遵守雙親委派,ExtClassLoader 會(huì)使用 Bootstrap ClassLoader 對(duì)類進(jìn)行加載)
        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)來(lái)加載
        try {
            clazz = Class.forName(name, false, parent);
            if (clazz != null) {
                if (resolve)
                    resolveClass(clazz);
                return clazz;
            }
        } catch (ClassNotFoundException e) {
            // Ignore
        }
     }
    //6. 上述過(guò)程都加載失敗,拋出異常
    throw new ClassNotFoundException(name);
}

(2)WebAppClassLoader 的 findClass() 方法源碼:

public Class<?> findClass(String name) throws ClassNotFoundException {
    // Ask our superclass to locate this class, if possible
    // (throws ClassNotFoundException if it is not found)
    Class<?> clazz = null;
 
    // 先在自己的 Web 應(yīng)用目錄下查找 class
    clazz = findClassInternal(name);
 
    // 找不到 在交由父類來(lái)處理
    if ((clazz == null) && hasExternalRepositories) {  
        clazz = super.findClass(name);
    }
    if (clazz == null) {
         throw new ClassNotFoundException(name);
    }
    return clazz;
}

4、為什么tomcat要實(shí)現(xiàn)自己的類加載機(jī)制:

WebAppClassLoader 加載類的時(shí)候,故意打破了JVM 雙親委派機(jī)制,繞開(kāi)了 AppClassLoader,直接先使用 ExtClassLoader 來(lái)加載類。最主要原因是保證部署在同一個(gè) Web 容器上的不同 Web 應(yīng)用程序所使用的類庫(kù)可以實(shí)現(xiàn)相互隔離,避免不同項(xiàng)目的相互影響。當(dāng)然還有其他原因,如:

(1)保證 Web 容器自身的安全不受部署的 Web 應(yīng)用程序影響,所以 Tomcat 使用的類庫(kù)要與部署的應(yīng)用的類庫(kù)相互獨(dú)立

(2)保證部分基礎(chǔ)類不會(huì)被同時(shí)加載,有些類庫(kù) Tomcat 與部署的應(yīng)用可以共享,比如說(shuō) servlet-api

(3)保證部署在同一個(gè) Web 容器的應(yīng)用之間的類庫(kù)可以共享,這聽(tīng)起來(lái)好像主要原因相互矛盾,但其實(shí)這很合理,類被類加載器加載到虛擬機(jī)后,會(huì)存放在方法區(qū)的永久代中,如果類庫(kù)不能共享,虛擬機(jī)的方法區(qū)就會(huì)很容易出現(xiàn)過(guò)度膨脹的風(fēng)險(xiǎn)。比如這時(shí)候如果有大量的應(yīng)用使用 spring 來(lái)管理,如果 spring 類庫(kù)不能共享,那每個(gè)應(yīng)用的 spring 類庫(kù)都會(huì)被加載一次,將會(huì)是很大的資源浪費(fèi)。

小結(jié):Tomcat 實(shí)際上只有 WebAppClassLoader 加載器中打破了雙親委派,其他類加載器還是遵循雙親委派的。 這樣做最主要原因是保證同個(gè) Web 容器中的不同 Web 應(yīng)用程序所使用的類庫(kù)相互獨(dú)立,避免相互影響

參考文章:https://www.jb51.net/article/229561.htm

到此這篇關(guān)于Tomcat的類加載機(jī)制流程及源碼解析的文章就介紹到這了,更多相關(guān)Tomcat類加載機(jī)制內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部