Tomcat 熱部署實現方式源碼分析總結

研究了一下tomcat的類的熱部署的源碼實現,總結沉澱一下。Tomat實現熱部署主要有兩種機制:html

(1) 一種是相似於Servlet這種類的熱部署即在WEB-INF/class目錄下的類:實現方式能夠歸納爲在容器啓動的時候起一條後臺線程,定時的檢測類文件的時間戳變化,若是類的時間戳變掉了,則調用容器的reload的方法,將類從新載入。web

那麼具體的分析一下:apache

tomcat用來加載servlet的類加載器是WebappClassLoader,但熱部署的邏輯不是在這個類加載器裏,而是封裝在了外圍的WebappLoader裏面(WebappClassLoader 是WebappLoader的成員變量)。WebappLoader做爲一個加載器,其實現了Loader接口,loader接口中定義了兩個和熱部署密切相關的方法即modified方法和backgroundProcess方法。Modified方法關聯了載入器中資源的變化狀況,而backgroundProcess則定義了後臺線程定時掃描時具體要執行的邏輯。tomcat

    Tomcat的啓動具體能夠分解爲各級容器的啓動(即:Engine,host,context 注意不包含Wrapper,Wrapper是在具體請求的時候初始化的)和鏈接器(默認兩種鏈接器Http,ajp)的啓動,另外固然還作了一些配置文件的解析這個很少說。app

    容器啓動根據tomcat的生命週期啓動方式是調用容器的start方法,start方法調用了具體的startInternal方法來作一些初始化的工做,其中就包括檢測類文件變化的後臺線程的初始化及啓動,具體看一下ContainerBase的StartInternal方法:spa

在這個方法的最後一行,調用了threadStart()方法,這個方法就是在啓動後臺線程,看一下方法體:線程

由這段代碼可知,這個方法啓動了一條線程,其中ContainerBackgroundProcessor必定是實現了Runnable接口的具體的後臺線程執行的邏輯,那就繼續看:調試

至此就看到了後臺線程的定義的真實面目,其中有個變量backgroundProcessDelay 這個變量的值會影響這條線程的睡眠時間,那也就說後臺線程定時執行的時間是可配置的。最後一行調用了processChildren方法,這個方法又是具體的執行邏輯,那麼斷點調試看下是如何完成了類的重載的。xml

ProcessChildren方法定義以下:htm

這裏調用了容器的backgroundProcess方法。Debug信息以下:

這個方法調用了載入器的WebappLoader的backgroundProcess方法。

標註處有兩個校驗項,一個是reloadable一個是modified方法。這個reloadable就是是否執行熱部署的開關,這個能夠在$CATALINA_HOME/conf/context.xml 當中配置一下,這個開關默認是不打開的。我修改了一下配置項以下:

Context.xml:

添加reloadable=true後,便可完成context容器的類的熱部署。修改以後調試信息以下:

再來看一下第二個校驗方法modified方法。這個modified方法會調用WebappClassLoader的Modified來判斷文件是否被修改。若是兩個校驗項都爲真的話,就會調用容器的reload方法(這裏說的容器是Context容器)

 Context容器的這個reload方法定義以下:

這個reload方法實現的仍是很簡單粗暴的,就是講整個Context容器重啓了一下,先stop,而後再start.(容器都重啓了,那容器課件範圍的類天然會被從新加載了)

       以上就是tomcat7.x實現WEB-INF/classes當中類熱部署的大致流程。除了WEB-INF/classes當中的類以外,還有一種特殊的類是默認熱部署的,這個就是JSP。

       (2)爲了實現JSP的加載部署,tomcat實現了另外一個加載器即org.apache.jasper.servlet.JasperLoader.JSP屬於一次消費品,每次訪問都會從新加載(網上說的,這個源代碼下次再研究下,在這先記錄下)

       (3)在讀源碼的時候身邊研究了下$CATALINA_HOME/conf/web.xml,這個配置文件是tomcat內置的配置文件,主要配置了兩個Servlet. 具體的配置以下:

DefaultServlet是要做用是爲靜態資源請求提供服務,包括圖片、html等。還有一個用來解析JSP的servlet:

JspServlet完成了Servlet的編譯,以及請求的處理。下面那個配置項<load-on-startup>的意思是當配置項的數值大於0時(數值越大被加載的優先級越低)就在容器啓動時候就加載這個Servlet 執行這個Servlet的init方法。

相關文章
相關標籤/搜索