Tomcat 源代碼分析之ClassLoader此系列文章皆為Tomcat 7.0代碼代碼分析。
1. ClassLoader基礎(chǔ)知識1.1. Parent-Child委托模型
我們知道Java系統(tǒng)中,類加載器的默認加載方式是采用Parent-Child委托方式加載類的,即就是說,先嘗試使用父類加載器加載類,如果沒有找到,才自己加載該類,可以看到,這是一個遞歸的加載過程,核心代碼大致如下:
很多ClassLoader的繼承類都默認了這種加載方式,其中用途比較廣泛的有URLClassLoader。
1.2. 類加載器運行時模型:
當一個JVM啟動時,至少有三個ClassLoader會被啟動: 1. Bootstrap 類加載器 加載Java核心包,它們被置放在(<JAVA_HOME>/lib目錄下,這部分是JVM的一部分,往往使用native code完成 2. Extensions類加載器 加載Java擴展包,即位于<JAVA_HOME>/lib/ext下的包,這里要注意的是,有些JVM的這個加載器和Bootstrap類加載器是同一個加載器,而Sun是把二者分開的,其實現(xiàn)類為sun.misc.Launcher$ExtClassLoader。 3. System類加載器 這個類加載器加載CLASSPATH下的類,Sun的 默認實現(xiàn)是sun.misc.Launcher$ExtClassLoader。 這三者之間的父子關(guān)系是:Bootstrap類加載器是Extensions類加載器的父類加載器,而Extensions類加載器是System類加載器的父類加載器。 2. Tomcat Classloader模型Tomcat 7.0的ClassLoader加載層次模型如下圖所示:
這個模型和之前Tomcat 5.5之前有些不同,因為之前的除過Common類加載器之外,還有Catalina類加載器和Shared類加載器,這個只能導(dǎo)致更多的配置和概念,已經(jīng)不再使用了,雖然還可以進行配置。 1. Common類加載器:加載$CATALINA_HOME/lib和$CATALINA_BASE/lib下的class文件和jar包以及旗下的資源文件,這些文件將會被所有Web應(yīng)用共有,也會被Tomcat運行時用到。其配置在catalina.properties下,如果沒有配置,則默認使用System類加載器,配置示例:
common.loader=${catalina.home}/lib,${catalina.home}/lib/*.jar
2. App類加載器:Web 應(yīng)用的類加載器,Web應(yīng)用下的資源文件,class文件盒jar包,按照Java Web規(guī)范的標準,它們位于Web應(yīng)用的/WEB-INF/classes和/WEB-INF/lib文件夾下。
3. 類加載器的實現(xiàn)
Tomcat類加載器其實有三個類實現(xiàn):StandardClassLoader,WebappClassLoader和JasperLoader,這三個類加載器都是URLClassLoader的子類。不同的是,StandardClassLoader并沒有客戶化URLClassLoader方法,即,它也是采用委托的方式加載類的。而其他都覆寫了loadClass()方法。 1. StandardClassLoader類加載器會創(chuàng)建Common類加載器的實例。 2. WebappClassLoader為每個應(yīng)用創(chuàng)建類加載器實例,對于加載Web應(yīng)用的類時,我們并非推薦使用父子委托模型,但是必須保證以java.*和javax.*開頭的包必須由System類加載器加載,即最終由Bootstrap加載器加載。 核心代碼如下:
可以看到,并非簡單的父子委托方式加載類 3. JasperLoader是為了加載jsp編譯成的servlet而創(chuàng)建的類加載器,它覆寫了loadClass()方法,除過加載org.apache.jsp.*的文件外,其他的均使用父加載器加載。 核心代碼如下:
今天就講到這里了。
|
|
|