天天看點

Tomcat源碼一:啟動Tomcat、解析xml

文章目錄

      • 下載下傳
      • 啟動:
      • 啟動過程:之解析xml的過程
      • 啟動過程:之初始化

下載下傳

Tomcat源碼 github位址下載下傳通道

啟動:

通過 啟動類 Bootstrap中的main方法啟動

啟動過程:之解析xml的過程

main方法中調用 load方法,load方法中通過反射,調用Catalina 類中的load方法

Tomcat源碼一:啟動Tomcat、解析xml

Catalina 中的load 方法 的解析

  • 建立 Digester(消化器),裡面包含解析xml的rules(規則)
    Tomcat源碼一:啟動Tomcat、解析xml
  • 通過digester 解析xml, 可以以項目根目錄下 conf檔案夾下的server.xml 為例
    Tomcat源碼一:啟動Tomcat、解析xml

啟動過程:之初始化

Tomcat源碼一:啟動Tomcat、解析xml
  1. createStartDigester() 方法詳解

關鍵是建構Digester 對象 digester,

digester 對象中有個屬性rules[RulesBase], rulesBase中有一個屬性 cache[Map<String,List>]

建立rule,就是在為cache put值。此處put的值,需要注意,後面會用來解析xml

Tomcat源碼一:啟動Tomcat、解析xml
  1. 解析xml詳解

第二個 digester 中比較重要的屬性是 stack[ArrayStack]

Tomcat源碼一:啟動Tomcat、解析xml

解析xml第一件事,就是把this,即Catalina的對象 pust到 stack中(此處的作用是為catalina對象,添加server屬性的值。後續會講)

然後開始 解析 conf檔案夾下的 server.xml 檔案。 采用的是 SAXParse 的方法,解析xml。即一行一行的解析(不要了解為一行一行的讀取) ⇒ SAXParse 詳解

  • startElement 方法 的解析

    圖一:

    Tomcat源碼一:啟動Tomcat、解析xml
    圖二:
    Tomcat源碼一:啟動Tomcat、解析xml

    圖一:createStartDigester 方法建構的rules

    圖二:match 是對 server.xml 元素 的拼接

    Tomcat源碼一:啟動Tomcat、解析xml
    第一個startElement,match = Server,比對圖一的 rules為
[ObjectCreateRule[className=org.apache.catalina.core.StandardServer, attributeName=className], 
 SetPropertiesRule[],
 SetNextRule[methodName=setServer, paramType=org.apache.catalina.Server]
 ]
           

然後挨個調用Rule的start方法,

ObjectCreateRule 的start方法 建立 StandardServer對象,并pust到digester的stack中

Tomcat源碼一:啟動Tomcat、解析xml

SetPropertiesRule的start方法 取(隻是擷取,并未出棧)之前push的對象,通過反射,為其指派屬性

Tomcat源碼一:啟動Tomcat、解析xml
Tomcat源碼一:啟動Tomcat、解析xml

SetNextRule 的start方法 通常是沒做什麼事情

Tomcat源碼一:啟動Tomcat、解析xml
  • endElement 方法解析
    *了解有難度的話,最好先熟悉 SAXParse,之後再對照着server.xml 檔案閱讀代碼*
               

之前是通過xml 元素拼接擷取的rule,tomcat巧妙的利用了xml,開始标簽和結束标簽 成對 出現的規則,startElement的時候,順序入棧,endElement的時候,順序出棧,可以保證Digest 對象中

stack元素存儲的 對象,與matches中存儲的規則,相對應。

Tomcat源碼一:啟動Tomcat、解析xml
Tomcat源碼一:啟動Tomcat、解析xml

開始對之前建立的對象,執行 end(個rule的執行順序,與start的順序剛好相反)

ObjectCreateRule[className=null, attributeName=className],
SetPropertiesRule[], 
SetNextRule[methodName=addLifecycleListener, paramType=org.apache.catalina.LifecycleListener]
           

SetNextRule 執行end() 方法

Tomcat源碼一:啟動Tomcat、解析xml

之前Catalina 對象中的 stack 屬性中 push的對象,是散的,各個對象沒有任何關系,相對獨立。

需要引用起來。根據 server.xml 可知,Listener元素的endElement處,會将 目前建立的 listener對象,添加到之前建立的Server中。

以此類推 整個server.xml 的解析中的 setNextRule中的end方法

便是 為StandardServer對象添加 多個listener 對象。

為StandardServer 添加 StandardService

為StandardService 添加 Connector 對象

最後将 StandardServer 添加到Catalina對象中,這就是 Catalina中的Server中 有值的原因

SetPropertiesRule 執行end() 方法

大部分都沒做什麼

ObjectCreateRule 執行end() 方法

目前處理的對象,出棧

Tomcat源碼一:啟動Tomcat、解析xml

後續轉 Tomcat源碼二

繼續閱讀