由于tomcat相對比較龐大我們無法去細(xì)細(xì)研究tomcat的所有實現(xiàn)細(xì)節(jié)。所以我打算只關(guān)注tomcat四到五個核心技術(shù)實現(xiàn)細(xì)節(jié)。不再關(guān)注其他的旁支末節(jié)。因為之前的文章寫過java類加載器,秉承知識的連續(xù)性,我們今天就來研究一下tomcat中的類加載實現(xiàn)機(jī)制。
首先我們打開idea,找到tomcatBootstrap類的main方法。這里是整個tomcat的入口main方法。

我們看到tomcat的main方法里只做了兩件事。第一件是執(zhí)行init方法。第二件事是監(jiān)聽各種啟動、關(guān)閉命令。我們只需要關(guān)注init方法里類加載器的初始化就可以了。我們進(jìn)入init方法里看看。

繼續(xù)進(jìn)入intitClassLoaders方法。

我們看見在這個方法里有三個類加載器,分別為commonLoader、catalinaLoader、sharedLoader。并且明白了他們的父子關(guān)系現(xiàn)在我們得到他們的關(guān)系如下

那么到這里tomcat所有類加載器就完了嗎?同學(xué)們,還是太年輕啊。如果到這里就完了的話,那tocmat作為一個servlet容器就至少有兩個問題沒有解決。1 各個web應(yīng)用jar包沖突。如tomcat想部署兩個web程序。兩個程序都用了spring框架,但是用的spring版本不一樣。在這樣情況下,如此的的類加載器顯然不能滿足這種需求,因為類加載器只能加載一次spring相關(guān)jar包。所有至少需要一個類加載器能隔離web應(yīng)用之間的jClass,這是其一,我們就姑且交叫這個類加載器為webappClassLoader吧(實際上,它就叫webappClassLoader,哈哈)。2 我們知道,tocmat是支持jsp的熱部署的,但是我們知道ClassLoader在加載過jsp對應(yīng)的Servlet后就不會再次加載了,那么怎么實現(xiàn)jsp的熱部署呢?把加載Servlet的ClassLoader也同時卸載掉就行了!再用新的classLoader再次加載jsp就可以實現(xiàn)。如果真的有這么一個類加載器的話,我們姑且就把這個類加載器稱為jaspLoader吧(實際上,它也就叫jaspLoader),所以一個jsp對應(yīng)一個JaspLoader?。?!。jsp簡直是皇帝般的待遇,有自己的獨棟別墅。
通過我們上面的分析我們知道tomcat肯定還有隱藏的。下次我們就把它們找出來?。?!
-----------------------------------------------------------完美的分界線接上更新----------------------------------------------------------
WebappClassLoader由于是web 應(yīng)用的私有類加載器。所以它的構(gòu)建過程在Context容器中(雖然還沒有開始研究Context相關(guān)源碼,但通過Context綁定一個WebappClassLoader是不是可以反向推導(dǎo)出一個Context對應(yīng)一個web應(yīng)用!tomcat中server.xml中關(guān)于Context的配置也從側(cè)面說明這一點)。
我們來看看StandardContext(Context的標(biāo)準(zhǔn)實現(xiàn)類)中關(guān)于WebappClassLoader的部分。

這部分代碼在StandardContext的startInternal方法中。如果我們將這段代碼得二行g(shù)etParentClassLoader()方法獲取到classLoader對象打印出來會發(fā)現(xiàn)它和我們上面構(gòu)建的sharedLoader是一個對象。WebappClassLoader的父類加載器是sharedLoader。我們還要關(guān)注一下WebappClassLoader.start()方法。它集成子它的父類WebappClassLoaderBase的start方法

我們看到了熟悉的WEB-INF/classes ?和/WEB-INF/lib,我明白了tomcat下的工程目錄為什么要這樣了。
JaspLoader呢?

我們再來看看它的父類加載器是什么?進(jìn)入getClassLoader方法

可以看到JaspLoader的父加載器是從線程中獲取的。那么是誰?

是webApplicationClassLoader至此我們已經(jīng)對tomcat的類加載完全了解。
