???????????????????????????? Tomcat5.5.16 部署web項(xiàng)目源碼詳解
Tomcat.5.5.16
安裝
web
項(xiàng)目時(shí)執(zhí)行的代碼主要是
HostConfig
類(lèi),其中
deployApps()
執(zhí)行部署
web
應(yīng)用的功能;
protected void deployApps() {
?
??????? File appBase = appBase();
??????? File configBase = configBase();
??????? // Deploy XML descriptors from configBase
????
???deployDescriptors(configBase, configBase.list());
??????? // Deploy WARs, and loop if additional descriptors are found
??????? deployWARs(appBase, appBase.list());
??????? // Deploy expanded folders
??????? deployDirectories(appBase, appBase.list());
?
??????
??? }?
從上面這段代碼,我們可以知道
tomcat
在部署
web
項(xiàng)目是按如下順序依次部署的;
1.???
首先部署
$CATALINA_HOME/conf/Catalina/localhost
目錄下面的
.xml
文件;
deployDescriptors(configBase, configBase.list());
(1)?????
configBase
的值是通過(guò)調(diào)用
configBase()
獲取的,
??
??File file = new File(System.getProperty("catalina.base"), "conf");
???
????Container parent = host.getParent();
??????? if ((parent != null) && (parent instanceof Engine)) {
??????????? file = new File(file, parent.getName());
??????? }
file = new File(file, host.getName());
可以看出
configBase
是由四部分內(nèi)容組成
;
System.getProperty("catalina.base")
+
“conf”
+
parent.getName()+host.getName()
parent.getName()
和
host.getName()
是分別取
server.xml
中
<Engine name="Catalina" defaultHost="localhost">
和
<Host name="localhost" appBase="webapps"? …
對(duì)應(yīng)的
name
屬性值;
由此可以得出
configBase
的值為
$CATALINA_HOME/conf/Catalina/localhost
?
???????
(2)
按文件名順序依次讀取
configBase
目錄下面的
xml
文件部署
web
應(yīng)用;
???????
???
第一步,首先獲取文件名(不包含
.xml
)作為上下文路徑
?????????????
??String nameTmp = files[i].substring(0, files[i].length() - 4);
??????????????? String contextPath = "/" + nameTmp.replace('#', '/');
?????
?????
第二步,解析
xml
文件,分析
docBase
的值;
???
注意這里的
docBase
的判斷很重要,采用和以前版本完全不同的做法;
?
????????????????????????????????
?if (!docBase.isAbsolute()) {
???????????????????
????docBase = new File(appBase(), context.getDocBase());
??????????????
?????
?}
?????????????????
首先判斷
docBase
是否為絕對(duì)路徑,如果不是絕對(duì)路徑,在改為
????
?????????????????
$CATALINA_HOME/webapps+docBase
??
???????????????
?????// If external docBase, register .xml as redeploy first
??????????????
????
?if(!docBase.getCanonicalPath().startsWith(appBase().getAbsolutePath()))
{
//
這個(gè)判斷很重要,這里是判斷如果
docBase
路徑是以
$ CATALINA_HOME/webapps+docBase
開(kāi)頭的字符串,則忽略掉了
???????????????????
?????
?isExternal = true;
???????????????????
?????? ...
???????????????????
???if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
???????????
????????????
????isWar = true;
???????????????????
???}
???????????????
???} else{
?????? // Ignore specified docBase
???? context.setDocBase(null);
}
??????????
?????????
從上面可以看出,
<Context path="/xxxx" docBase="xxxx" .
中
docBase
只有為絕對(duì)路徑并且該路徑不是以
$CATALINA_HOME/webapps
開(kāi)頭,才會(huì)生效;否則就忽略掉了;
?
?
2.???
接下來(lái)部署
$CATALINA_HOME/webapps/
目錄下以。
War
結(jié)尾的文件
deployWARs(appBase, appBase.list());
(1)
首先仍是把文件名
(
不用
.war)
作為其應(yīng)用的上下文路徑
;
?
?
?if (files[i].toLowerCase().endsWith(".war")) {
??????????????? // Calculate the context path and make sure it is unique
??????????????? String contextPath = "/" + files[i];
??????????????? int period = contextPath.lastIndexOf(".");
???????
(2)
接下來(lái)判斷以該上下文路徑
contextPath
是否已經(jīng)裝載過(guò)了,如果是則直接退出;
??
?if (deploymentExists(contextPath))
???????????
?????????return;
??????
(
3
)
繼續(xù)判斷以該上下文命名的部署文件是否存在,如
war
文件為
AAA.war,
則判斷在
$CATALINA_HOME/conf/Catalina/localhost/AAA.xml
文件是否存在,如果不存在繼續(xù)執(zhí)行以下操作;
?????????
?
?File xml = new File
??????????? (configBase, file.substring(0, file.lastIndexOf(".")) + ".xml");
??????? if (deployXML && !xml.exists()) {
????????? entry = jar.getJarEntry(Constants.ApplicationContextXml);
????????? configBase.mkdirs();
?????????
。。。
?????
先從
wart
文件中讀取
META-INF/context.xml
文件,然后把它
copy
到
????? $CATALINA_HOME/conf/Catalina/localhost/AAA.xml,
注意
war
文件部署文件必須為
context.xml
,且在
META-INF
目錄下;
??
?
(
4
)接下來(lái)操作和上面類(lèi)似,部署該
web
應(yīng)用;
3.
最后是以
$CATALINA_HOME/webapps
目錄下的文件夾為目標(biāo)按文件夾名順序進(jìn)行部署;
?
?
?deployDirectories(appBase, appBase.list());
(1)??????
同樣先把該文件夾名作為上下文路徑進(jìn)行部署;
????????
?
??File dir = new File(appBase, files[i]);
??????????? if (dir.isDirectory()) {
?
??????????????? // Calculate the context path and make sure it is unique
??????????????? String contextPath = "/" + files[i];
?????????????
(2)??????
接下來(lái)的步驟就基本上是一樣了,首先判斷該上下文路徑是否已經(jīng)部署過(guò),如果是則直接退出,否則和上面一樣,讀取
META-INF/context.xml
文件進(jìn)行部署;
注意這里和上面的
war
文件部署稍微有點(diǎn)不同,就是它不會(huì)
copy
部署文件
context.xml
文件到
$CATALINA_HOME/conf/Catalina/localhost
中去;
?
?
?