Tomcat中的類是怎麼被一步步載入的?

java填坑路發表於2018-09-17

瞭解Tomcat的類載入機制,原來一切是這麼的簡單。

一、類載入

在JVM中並不是一次性把所有的檔案都載入到,而是一步一步的,按照需要來載入。

比如JVM啟動時,會通過不同的類載入器載入不同的類。當使用者在自己的程式碼中,需要某些額外的類時,再通過載入機制載入到JVM中,並且存放一段時間,便於頻繁使用。

因此使用哪種類載入器、在什麼位置載入類都是JVM中重要的知識。

二、JVM類載入

JVM類載入採用:父類委託機制,如下圖所示:

JVM中包括集中類載入器:

BootStrapClassLoader 引導類載入器

ExtClassLoader 擴充套件類載入器

AppClassLoader 應用類載入器

CustomClassLoader 使用者自定義類載入器

他們的區別上面也都有說明。需要注意的是,不同的類載入器載入的類是不同的,因此如果使用者載入器1載入的某個類,其他使用者並不能夠使用。

當JVM執行過程中,使用者需要載入某些類時,會按照下面的步驟(父類委託機制)

使用者自己的類載入器,把載入請求傳給父載入器,父載入器再傳給其父載入器,一直到載入器樹的頂層。

最頂層的類載入器首先針對其特定的位置載入,如果載入不到就轉交給子類。

如果一直到底層的類載入都沒有載入到,那麼就會丟擲異常ClassNotFoundException。

因此,按照這個過程可以想到,如果同樣在CLASSPATH指定的目錄中和自己工作目錄中存放相同的class,會優先載入CLASSPATH目錄中的檔案。

三、Tomcat類載入

在Tomcat中類的載入稍有不同,如下圖:

 

當Tomcat啟動時,會建立幾種類載入器:

1、Bootstrap 引導類載入器

載入JVM啟動所需的類,以及標準擴充套件類(位於jre/lib/ext下)

2、System 系統類載入器

載入Tomcat啟動的類,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位於CATALINA_HOME/bin下。

3、Common 通用類載入器

載入Tomcat使用以及應用通用的一些類,位於CATALINA_HOME/lib下,比如servlet-api.jar

歡迎工作一到五年的Java工程師朋友們加入Java架構開發:744677563 群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用”沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!

4、webapp 應用類載入器

每個應用在部署後,都會建立一個唯一的類載入器。該類載入器會載入位於 WEB-INF/lib下的jar檔案中的class 和 WEB-INF/classes下的class檔案。

當應用需要到某個類時,則會按照下面的順序進行類載入

1、使用bootstrap引導類載入器載入

2、使用system系統類載入器載入

3、使用應用類載入器在WEB-INF/classes中載入

4、使用應用類載入器在WEB-INF/lib中載入

5、使用common類載入器在CATALINA_HOME/lib中載入

四、問題擴充套件

通過對上面Tomcat類載入機制的理解,就不難明白 為什麼Java檔案放在Eclipse中的src資料夾下會優先jar包中的class?

這是因為Eclipse中的src資料夾中的檔案Java以及webContent中的JSP都會在Tomcat啟動時,被編譯成class檔案放在 WEB-INF/class中。

而Eclipse外部引用的jar包,則相當於放在 WEB-INF/lib 中。

因此肯定是 Java檔案或者JSP檔案編譯出的class優先載入

通過這樣,我們就可以簡單的把Java檔案放置在src資料夾中,通過對該Java檔案的修改以及除錯,便於學習擁有原始碼Java檔案、卻沒有打包成xxx-source的jar包。

另外呢,開發者也會因為粗心而犯下面的錯誤。

在 CATALINA_HOME/lib 以及 WEB-INF/lib 中放置了 不同版本的jar包,此時就會導致某些情況下報載入不到類的錯誤。

還有如果多個應用使用同一jar包檔案,當放置了多份,就可能導致 多個應用間 出現類載入不到的錯誤。

為什麼某些人會一直比你優秀,是因為他本身就很優秀還一直在持續努力變得更優秀,而你是不是還在滿足於現狀內心在竊喜!

歡迎工作一到五年的Java工程師朋友們加入Java架構開發:744677563

群內提供免費的Java架構學習資料(裡面有高可用、高併發、高效能及分散式、Jvm效能調優、Spring原始碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用自己每一分每一秒的時間來學習提升自己,不要再用”沒有時間“來掩飾自己思想上的懶惰!趁年輕,使勁拼,給未來的自己一個交代!


相關文章