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