Tomcat8源碼筆記(八)明白Tomcat怎么部署webapps下項目


      以前沒想過這么個問題:Tomcat怎么處理webapps下項目,並且我訪問瀏覽器ip: port/項目名/請求路徑,以SSM為例,Tomcat怎么就能將請求找到項目呢,項目還是個文件夾類型的?

 

      Tomcat部署webapps下項目方法位於:HostConfig#deployApps,別問怎么知道的,看源碼,也可以支持看下我前面的博客,雖然介紹粗枝大葉,但是也能走到這步了。

介紹下deployApps,最開始獲取兩個配置,分別是catalina-home/webapps以及catalina-home/conf/Catalina/localhost路徑,filterAppPaths方法呢主要是過濾webapps下不想部署的項目,比如你有些大項目以前部署的,現在不想用了,但是不想刪除呢?就可以忽略部署來節省Tomcat啟動時間,具體方式就是在server.xml中Host元素里添加屬性deployIgnore,支持正則表達式過濾。

deployDescriptors、deployWARs是部署特定類型的項目,比如war包等,這里主要介紹的是deployDirectories,有興趣的可以自行研究另外兩種.

image

 

     那我們明白了Tomcat部署項目還是得靠deployDirectories方法.

HostConfig#deployDirectories方法如下,思路清晰,先介紹個大體,webapps下每個項目,只要是文件夾的(名字不為META-INF\WEB-INF)的,都會通過多線程的方式去”部署項目”,(這里需要提及一點,怕引起誤會,這里Tomcat默認給配置的ExecutorService初始線程個數、最大線程個數都是1,這個就尷尬了,是啥原因引起的無從而就,如果調大個數是否能提高銷量有待確認!)下面開始一點點介紹這個“部署”過程.

image

 

第一步,介紹ContextName實例化

    name是webapps下各個文件夾類項目的名字,FWD_SLASH_REPLACEMENT就是 # ,VERSION_MARKER就是 ## , 代碼比較簡單,直接看結果,比如webapps下doc目錄,最后得到的四個屬性值結果就是 baseName就是docs ,version就是 “”,path就是 /docs ,name就是 /docs , 其他正常項目名不含#都是類似,舉兩個個例:Root目錄,baseName是Root,version就是“” , path就是 “”, name就是 “”  .

image

 

 

第二步.線程來調用DeployDirectory完成部署

DeployDirectory是HostConfig內部類,實現了Runnable,持有三重要屬性:HostConfig--外部類實例,ContextName--上面初始化的上下文名稱類,File---當前webapps下目錄的File句柄

run方法是核心,一看還不是調用HostConfig#deployDirectory!

image

第三步. HostConfig#deployDirectory部署項目

代碼比較長,分成片段來記錄:  前幾行打印日志,就是Tomcat常見到的日志如下.  然后  xml文件引用指向 webapps下當前正在部署的項目(暫叫A吧),xml指向A項目META-INF/content.xml文件,而xmlCopy指向 catalina-home/conf/Catalina/localhost/A.xml,copyThisXml默認是false,deployThisXML默認是true.

Deploying web application directory E:\Tomcat_Source_Code\apache-tomcat-8.0.53-src\catalina-home\webapps\docs

image 代碼片段二. 截取了try-catch塊前半段, 由於deployThisXML默認是true,但是我們假設content.xml不存在的情況,就會執行if判斷邏輯最后一段,contextClass默認是StandardContext,所以實例化了一個StandardContext!

image

代碼片段三. try-catch塊后半段邏輯:configClass默認是ContextConfig,是個Tomcat的監聽器,實例化后在StandardContext上監聽着,此外StandardContext賦值四個ContextName的屬性.

然后將StandardContext和StandardHost關聯起來!  代碼片段四.finally塊做了一些收尾工作,這個留待時候再分析,先分析StandardContext與StandardHost的關聯!

image

StandardHost和StandardContext關聯起來步驟比較復雜!

  先判斷是否webapps是否有項目名解析之后name一樣的,拋出異常來不允許這樣做!將StandardContext父類設置為StandardHost,將StandardContext作為value,項目名name作為key存入StandardHost的 children屬性中(這也說明StandardHost的getChildren肯定是調用children.values()來獲取);   部署一個項目之后就會調用項目StandardContext#start方法,項目啟動之后觸發對應監聽事件.  StandardContext#start簡單分析見這里,Tomcat8源碼筆記(九)組件StandardContext啟動流程--未完待續 

image

代碼片段四.finally塊

部署完成之后,最終達成這樣的效果,將部署信息存放在HostConfig的deployed中,比如 /docs--對應部署信息.

image

大體流程粗糙的寫了一遍,具體細節,類我還需要熟悉在記錄吧。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM