Tomcat源碼閱讀1

系統的啓動流程:

tomcat通常從腳本啓動,查看腳本可知,startup.sh中調用了catalina.sh進行啓動,而在catalina.sh中,可以看到時啓動了Bootstrap類

  org.apache.catalina.startup.Bootstrap "$@" start

從bootstrap類的main方法開始啓動,此類中有

private Object catalinaDaemon = null ; 
protected ClassLoader commonLoader = null ;
protected ClassLoader catalinaLoader = null ;   

等,首先new boostrap對象,調用init方法,init方法中先調用initClassLoader方法,獲取 三種ClassLoader,分別是:commonLoader、catalinaLoader 、sharedLoader ,在此說明一句,如果commonLoader初始化失敗,即沒有config配置文件,則將bootstrap的Classloader賦值給commonLoader。
先從commonLoader說起,

 String value = . getProperty(name + ".loader");

此處使用了CatalinaProperties類,這個類有

static{
     loadProperties();
}

會隨着類的加載而運行,加載了加載Catalina.Properties配置文件,通過字符串common.loader獲取此屬性文件對應的配置:

common.loader="${catalina.base}/lib", "${catalina.home}/lib/*.jar"

然後通過replace方法處理拿到的字符串,替換爲對應config目錄; D:\SVN\CodeLearning\Tomcat8\output\build/lib,根據四種模式:DIR JAR URL GLOB去掃描相應類,最後通過

ClassLoaderFactory. createClassLoader(repositories, parent)

方法,將String類型的加載路徑字符串穿進去,在此方法中使用LinkedHashSet,掃描將要加載的類,對應四種不同的模式,然後將這個LinkedHashSet.toArray,賦值給鏈表,最後

     return new URLClassLoader(array);

把要加載路徑賦值進去,返回一個URLClassLoader,並加載各種類。所以commonLoader就是URLClassLoader。接上面的,如果沒有config,則使用bootstrap的ClassLoader給commonLoader。
同理,catalinaLoader和sharedLoader的加載方式:

catalinaLoader = createClassLoader( "server", commonLoader );   
 sharedLoader = createClassLoader("shared" , commonLoader );

由此可見commonloader是其父類加載器。不過server.loader和sharedLoader在Catalina.properties中沒配置屬性。當調用 catalinaLoader = createClassLoader( “server” , commonLoader );
sharedLoader = createClassLoader(“shared” , commonLoader );
時,

        String value = CatalinaProperties. getProperty(name + ".loader");
        if ((value == null) || (value.equals("")))
            return parent;

由於properties文件沒有對應的server.loader和shared.loader屬性,古直接返回URLClassLoader加載器。

綜上,三種加載器初始化完畢,調用Thread. currentThread().setContextClassLoader( catalinaLoader);
將catalinaLoader設置爲當前線程的加載器。 然後調用

Class<?> startupClass =   catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina");

在加載catalina類,使用反射,調用其setParentClassLoader方法,參數爲java.lang.ClassLoader.

然後調用catalina的isAwait和start方法,啓動服務器。

Method method = catalinaDaemon.getClass().getMethod ("start" , (Class [] )null );

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章