引入:
在上文中,我們從宏觀上講解了Liferay部署war包的動作是如何觸發監聽器並且完成部署過程的,但是其中最核心的一塊deployDirectory我們沒講,它的作用是當有了臨時目錄並且已經把war包的內容展開到該目錄之後,是如何對其中內容進行解析,再加工並且最終複製到最終的部署目錄deployDir的,我們這裡就研究這塊內容:
調試分析:
首先,我們看下這個複雜方法的入參:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545321F6-0.png" title="41.png" />
srcFile參數是我們臨時目錄,也就是被展開的war檔案對應的目錄。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322c5-1.png" title="42.png" />
mergeDir是一個目錄,用於merge的,我們設定為在LIFERAY部署目錄$LIFERAY_HOME/deploy)中建一個merge目錄,然後以我們的war包名字為子目錄,如下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532K94-2.png" title="43.png" />
deployDir不用說了, 也就是在tomcat的webapps目錄下我們的應用最終要放置到的目錄:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/15453231O-3.png" title="44.png" />
後面3個參數不用說了。
我們開始分析:
首先在第514行調用rewriteFiles去重寫臨時目錄中srcDir中的幾個檔案:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532E10-4.png" title="45.png" />
代碼我不貼了,一看就懂,它的目的是對於web.xml, liferay-plugin-package.xml,liferay-display.xml,liferay-portlet.xml,portlet.xml這5個檔案進行子項目的縮排,並且縮排量都是一個定位字元的距離。所以最終檔案都會變成:
<parent-ele>
<child-ele>
這種縮排格式
接著在第516行中調用mergeDirectory(mergeDir,srcFile)方法,.因為我們的mergeDir為空白,所以直接這段代碼跳過。
接著在第518行調用processPluginPackageProperties(srcFile,displayName,pluginPackage)對於plugin package的properties檔案進行處理,因為我們沒有liferay-plugin-package.properties,取而代之我們是用xml檔案的,所以這段代碼也跳過。
接著會在第520行調用copyJars(srcDir,pluginPackage) 方法,
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322a6-5.png" title="46.png" />
他們會吧$CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies目錄下的多個jar檔案
分別複製到我們srcFile指定的portlet臨時目錄下的WEB-INF/lib目錄下。
細心的你一定會問,為什麼突然多出來$CATALINA_HOME/liferay/com/liefray/portal/deploy/dependencies目錄,為什麼會有這麼多jar檔案?其實我也不知道,我們在最後“精華疑點解答中”會分析,這裡姑且假定這個目錄已經存在並且由這些jar檔案吧。
然後在第521行調用copyProperties(srcFile,pluginPackage)方法。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545325B6-6.png" title="47.png" />
細節我省去了,它會去吧logging.properties,log4j.properties,service.properties等這些檔案從$CATALINA_HOME/temp/liferay/com/liferay/portal/deploy/dependencies目錄
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545325V1-7.png" title="48.png" />
複製到我們用srcFile變數指定的portlet臨時目錄下的WEB-INF/class目錄下。
接下來它會在第522行調用copyTlds(srcFile,pluginPackage)方法:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322534-8.png" title="49.png" />
他們會吧aui.tld,liferay-portlet.tld,liferay-portlet-ext.tld,liferay-security.tld,liferay-theme.tld,liferay-ui.tld,liferay-util.tld這些Taglib定義檔案都複製到我們用srcFile變數指定的portlet臨時目錄下的WEB-INF/tld目錄下,那麼這些原始檔案在哪裡呢?也許你猜對了,他們還是在$CATALINA_HOME/temp/liferay/com/liferay/portal/deploy/dependencies 目錄下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532FV-9.png" title="50.png" />
接下來它會去調用copyXmls(srcFile,displayName,pluginPackage)方法。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532C57-10.png" title="51.png" />
首先它會調用super.copyXmls,這個的作用是用來判斷伺服器類型來確定如何去複製伺服器特定的xml檔案和web.xml檔案到我們用srcFile變數指定的portlet臨時目錄下的WEB-INF目錄下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322D6-11.png" title="52.png" />
因為我們的appServerType是"tomcat",所以它不會複製伺服器特定的xml檔案,只會複製一個web.xml。
然後因為我們appServerType是'tomcat",所以它會複製context.xml檔案到我們用srcFile變數指定的portlet臨時目錄下的/META-INF目錄下。
最後會吧_servlet_context_include.jsp檔案複製到我們用srcFile變數指定的portlet臨時目錄下的/WEB-INF/jsp目錄下.
那麼這些xml檔案是不是還是在$CATALINA_HOME/temp/liferay/com/liferay/portal/deploy/dependencies 目錄下呢?回答正確~
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532Jc-12.png" title="53.png" />
接下來它在第524行調用copyPortalDependencies(srcFile) ,因為我們沒有定義plugin package的properties檔案,所以這行沒執行。
接下來它在第530行調用updateWebXml(webXml,srcFile,displayName,pluginPackage)方法對於我們從$CATALINA_HOME/temp/liferay/com/liferay/portal/deploy/dependencies目錄下直接複製來的最原始的xml進行更新,對其中內容進行了增刪,關於這一塊也十分複雜, 我準備另外用一文章來介紹)
接下來對於/WEB-INF/ext-lib/global和/WEB-INF/ext-lib/portal中的jar包處理,把他們複製到liferay 伺服器上的對應目錄,因為我們沒有,所以跳過。
接下來在第558行,調用updateDeployDirectory(srcFile)對部署目錄進行更新。
然後對於jar包進行排除操作了:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545325127-13.png" title="55.png" />
首先,它先判斷伺服器類型,因為我們是tomcat ,所以它會去吧tomcatLibDir中的所有的jar包都放在排除清單中,這個tomcatLibDir是
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532F10-14.png" title="56.png" />
然後它會去讀取剛才conext.xml,如果其中指定了com.liferay.support.tomcat.loader.PortalClassLoader,那麼就去掉3個jar包。
然後把**/WEB-INF/web.xml也加在exclude列表中,因為這web.xml總要被改動的,所以我們這個檔案不會最終複製到tomcat下的webapps下我們應用的deployDir中。最終我們的exclude列表如下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322C6-15.png" title="58.png" />
然後第674行執行複製動作,它吧我們的$CATALINA_HOME/temp/<時間戳記下>的我們的臨時的應用資訊去除exclude列表中的web.xml和一些jar檔案其他全部複製到$CATALINA_HOME/webapps/<項目名>這個最終部署目錄下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/154532EP-16.png" title="57.png" />
最後第678行單獨複製web.xml檔案,並且overrite設定為true, 表示覆蓋原有的。我們從伺服器的所有檔案時間戳記可以看到這一點,如下:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/15453223D-17.png" title="60.png" />
從上面我們可以看到WEB-INF目錄下,只有最後一行的web.xml的時間戳記比較上次發生了改變,這就表明這個web.xml是單獨複製的,實踐果然和代碼執行相互吻合。
最後第690行吧這個新產生的web.xml的lastModified設定為當前的時間+6秒。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545323395-18.png" title="61.png" />
最最後吧我們吧tempDir(也就是我們在$CATALINA_HOME/temp/<時間戳記>)這個目錄刪除,
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545322608-19.png" title="62.png" />
就一切大功告成了,從deployDirectory()方法返回。
精華疑點解答:
在總結之前,還有一個疑惑沒明白,就是我們看部署的很多動作都是要先從$CATALINA_HOME/liferay/com/liefray/portal/deploy/dependencies目錄中吧各種檔案,包括properties檔案,tld檔案,xml檔案等)複製到tempDir中,那麼這個檔案是何時產生的又是為什麼包含這麼多內容呢?我們現在來專門研究這個問題。
很快就找到了答案,它這些內容從classpath複製到$CATALINA_HOME/temp/liferay 目錄下的。
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545324928-20.png" title="64.png" />
而classpath這些檔案,經過仔細尋找,發現都來自於$CATALINA_HOME/webapps/ROOT/WEB-INF/lib/portal-impl.jar ,比如說所有用到的tld檔案:
650) this.width=650;" src="http://www.bkjia.com/uploads/allimg/131228/1545321T8-21.png" title="65.png" />
總結:
(1)deployDirectory的整體作用是在tomcat的temp目錄擁有一個從war包展開的目錄結構然後經過一些配置,重組,最後複製到webapps下響應應用的部署目錄的過程。
(2)首先它會調用rewriteFiles去重寫目錄下的幾個xml檔案,目的是讓檔案更規範,有縮排的格式。
(3)然後它會讀取plugin-package.properties中的屬性設定到Properties中。
(4)然後調用copyJars()方法吧CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies目錄下的多個jar檔案分別複製到我們srcFile指定的portlet臨時目錄下的WEB-INF/lib目錄下。
(5)然後調用copyProperties吧CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies
目錄下的多個properties檔案分別複製到我們srcFile指定的portlet臨時目錄下的WEB-INF/classes目錄下.
(6)然後調用copyTlds吧CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies
目錄下的多個tld檔案分別複製到我們srcFile指定的portlet臨時目錄下的WEB-INF/tld目錄下.
(7)然後調用copyXmls方法,先根據伺服器類型來決定吧伺服器特定的xml檔案和web.xml檔案複製到我們srcFile指定的portlet臨時目錄下的WEB-INF目錄下,如果是tomcat伺服器還要複製context.xml檔案到portlet臨時目錄下的META-INF目錄下,然後把_servlet_context_include.jsp複製到portlet臨時目錄下的WEB-INF/jsp目錄下。以上檔案都是從CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies目錄中擷取的。
(8)然後調用updateWebXml(webXml,srcFile,displayName,pluginPackage)方法對於我們從$CATALINA_HOME/temp/liferay/com/liferay/portal/deploy/dependencies目錄下直接複製來的最原始的xml進行更新,對其中內容進行了增刪這個放在以後文章中單獨討論)
(9)接下來對於/WEB-INF/ext-lib/global和/WEB-INF/ext-lib/portal中的jar包處理,把他們複製到liferay 伺服器上的對應目錄
(10)從第(4)-(8)中的每一步複製,這些資源檔都是來自於CATALINA_HOME/liferay/com/liferay/portal/deploy/dependencies 目錄,而這些資源檔最初都是來自$CATALINA_HOME/webapps/ROOT/WEB-INF/lib/portal-impl.jar中,這些資源在Liferay運行後會被載入到classpathResource中。
(11)在最終複製到webapps下的部署目錄之前,它必須要先產生一個排除清單,表明在複製時候那些資源要先排除,web.xml總是被排除的, 另外還有一些jar檔案,取決於我們的配置。
(12)複製到webapps下部署目錄的動作總是分為2部分,一是複製除排除清單中的所有檔案目錄,二是單獨複製web.xml檔案,所以每次可以看到web.xml的時間戳記總比其他檔案晚。
(13)最後複製完會到webapps下我們應用的部署目錄下把最新的web.xml的lastModified屬性往後面調6秒。
本文出自 “平行線的凝聚” 部落格,請務必保留此出處http://supercharles888.blog.51cto.com/609344/1286631