成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術(shù)文章
文章詳情頁

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

瀏覽:147日期:2023-03-19 16:51:42
目錄
  • 前言
  • 1、Tomcat 的類加載器結(jié)構(gòu)圖:
  • 2、Tomcat 的類加載流程說明:
  • 3、源碼解析:
  • 4、為什么tomcat要實(shí)現(xiàn)自己的類加載機(jī)制:

前言

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

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

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

(3)若沒有加載則調(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),并重寫其中的 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)⽤程序不能訪問;

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

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

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

2、Tomcat 的類加載流程說明:

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

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

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

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

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

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

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

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

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)加載過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類加載器類加載(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)來加載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);}

(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);     // 找不到 在交由父類來處理    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ī)制,繞開了 AppClassLoader,直接先使用 ExtClassLoader 來加載類。最主要原因是保證部署在同一個(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)用可以共享,比如說 servlet-api

(3)保證部署在同一個(gè) Web 容器的應(yīng)用之間的類庫(kù)可以共享,這聽起來好像主要原因相互矛盾,但其實(shí)這很合理,類被類加載器加載到虛擬機(jī)后,會(huì)存放在方法區(qū)的永久代中,如果類庫(kù)不能共享,虛擬機(jī)的方法區(qū)就會(huì)很容易出現(xiàn)過度膨脹的風(fēng)險(xiǎn)。比如這時(shí)候如果有大量的應(yīng)用使用 spring 來管理,如果 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)文章希望大家以后多多支持!

標(biāo)簽: Tomcat
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
自拍偷拍亚洲综合| 精品视频一区 二区 三区| 国产乱码字幕精品高清av| 毛片一区二区三区| 欧美a级一区二区| 美脚の诱脚舐め脚责91| 美日韩一区二区三区| 免费成人av资源网| 久久国产福利国产秒拍| 精品国产一区二区精华| 精品久久久久99| 久久精品夜色噜噜亚洲aⅴ| 国产性做久久久久久| 国产精品亲子乱子伦xxxx裸| 日韩伦理av电影| 午夜精品123| 美女视频黄免费的久久| 国产丶欧美丶日本不卡视频| va亚洲va日韩不卡在线观看| 亚洲欧美在线观看| 亚洲精品日产精品乱码不卡| 日韩精品一区第一页| 久久成人精品无人区| 岛国精品在线观看| 国内一区二区在线视频观看| 国产视频一区欧美| 欧美性受极品xxxx喷水| 精品国产免费人成在线观看| 亚洲欧洲av色图| 欧美日韩精品一区视频| 欧美成人a∨高清免费观看| 国产精品女主播在线观看| 亚洲国产另类av| 国产精品资源在线看| 欧美视频久久| 91国产免费观看| 久久综合久久99| 亚洲国产你懂的| 国产毛片精品视频| 亚洲精品日韩一| 国产伦精品一区二区三区免费 | 欧美jizzhd精品欧美巨大免费| 日韩视频在线观看国产| 欧美日韩二区三区| 国产精品国产三级国产| 捆绑紧缚一区二区三区视频| www.久久久久久久久| 国产精品一区视频| 欧美视频一区| 欧美日韩一区二区三区高清| 国产欧美综合在线| 蜜臀av性久久久久蜜臀av麻豆| aaa亚洲精品| 一本一道综合狠狠老| 久久综合色之久久综合| 日韩综合小视频| 欧美日韩国产综合网| 欧美日韩中字一区| 亚洲免费观看在线视频| 国产成人h网站| 久久久久久夜| 国产精品久久久久桃色tv| 国产精品影音先锋| 老鸭窝91久久精品色噜噜导演| 26uuu精品一区二区在线观看| 日韩国产在线一| 一区二区视频在线观看| 欧美哺乳videos| 韩国一区二区在线观看| 午夜综合激情| 中文字幕亚洲区| 99精品视频在线播放观看| 欧美在线999| 亚洲va天堂va国产va久| 韩日欧美一区| 国产日韩欧美不卡在线| 岛国av在线一区| 欧美美女直播网站| 午夜精品123| 夜夜精品视频| 国产精品久久久久国产精品日日| 国产91丝袜在线播放0| 在线观看亚洲精品视频| 亚洲香肠在线观看| 亚洲精品在线视频观看| 国产精品午夜在线观看| 91免费观看在线| 精品国产乱码久久久久久蜜臀| 国产一区二区伦理| 欧美日产国产精品| 麻豆一区二区99久久久久| 国产永久精品大片wwwapp | 国产女人aaa级久久久级| 成人国产亚洲欧美成人综合网 | 在线精品视频免费观看| 日韩综合一区二区| 欧美中文日韩| 亚洲超碰97人人做人人爱| 日韩午夜免费视频| 亚洲乱码中文字幕综合| 一区二区福利| 亚洲国产裸拍裸体视频在线观看乱了| 日韩国产精品久久| 91国偷自产一区二区开放时间| 午夜精品久久久久久久蜜桃app| 亚洲一区网站| 日韩不卡一区二区| 欧美日韩aaaaaa| 成人美女视频在线看| 2019国产精品| 欧美午夜电影在线观看| 成人免费在线观看入口| 国产精品毛片一区二区三区 | 亚洲黄色在线视频| 欧美一级专区| 美女精品一区二区| 日韩一区和二区| 91免费国产视频网站| 国产精品电影一区二区三区| 亚洲最新在线| 日韩专区欧美专区| 欧美一级艳片视频免费观看| thepron国产精品| 亚洲精品国产精华液| 色婷婷久久99综合精品jk白丝| 久久 天天综合| 久久只精品国产| 夜久久久久久| 国产在线视频不卡二| 久久亚洲二区三区| 亚洲美女色禁图| 美女视频一区二区| 久久久久久久久一| 久久av在线| 成人美女在线视频| 亚洲精品国产视频| 9191国产精品| 亚洲国产日韩美| 美女视频网站久久| 国产午夜亚洲精品不卡| 色哟哟在线观看一区二区三区| 国产高清精品网站| 亚洲美女少妇撒尿| 制服丝袜在线91| 亚洲大黄网站| 国产乱对白刺激视频不卡| 国产精品久久久久久久久快鸭 | 国产精品激情偷乱一区二区∴| 欧美专区在线观看一区| 欧美va天堂在线| 蜜臀99久久精品久久久久久软件| 久久亚洲二区三区| 91黄色免费版| 极品av少妇一区二区| 国产精一区二区三区| 亚洲欧美日韩国产成人精品影院| 欧美一区在线视频| 国产精品一页| 欧美高清视频一区| 韩国女主播成人在线| 一区二区在线免费| 久久免费国产精品| 精品视频一区二区三区免费| 99riav1国产精品视频| 国产成人激情av| 日韩精品一区第一页| 成人免费一区二区三区视频| 不卡一区二区三区四区| 蜜臀av性久久久久蜜臀aⅴ流畅| 亚洲欧洲精品天堂一级| 欧美v亚洲v综合ⅴ国产v| 色一情一伦一子一伦一区| 亚洲国产精品久久人人爱| 久久久久久久久久久黄色| 精品视频全国免费看| 国产精品一区二区欧美| 午夜视频一区| 99久久久国产精品免费蜜臀| 美女网站视频久久| 亚洲成av人片www| 亚洲欧美激情插| 国产精品久久二区二区| 国产欧美视频一区二区| 精品免费日韩av| 日韩一区二区三区电影在线观看 | 欧美日韩成人高清| 色一情一乱一乱一91av| 性感少妇一区| 国产精品久久久久久久免费软件 | 欧美日韩调教| 欧美一区2区三区4区公司二百 | 日韩欧美一区在线| 欧美二区三区的天堂| 欧美三级韩国三级日本一级| 狼狼综合久久久久综合网| 久久久久久穴| 色综合激情五月| 91成人在线免费观看| 在线观看视频一区二区| 色视频欧美一区二区三区|