Tomcat5.5.16 部署web项目源码详解
Tomcat.5.5.16
安装
web
项目时执行的代码主要是
HostConfig
类,其中
deployApps()
执行部署
web
应用的功能;
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
项目是按如下顺序依次部署的;
1.
首先部署
$CATALINA_HOME/conf/Catalina/localhost
目录下面的
.xml
文件;
deployDescriptors(configBase, configBase.list());
(1)
configBase
的值是通过调用
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
是由四部分内容组成
;
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" …
对应的
name
属性值;
由此可以得出
configBase
的值为
$CATALINA_HOME/conf/Catalina/localhost
(2)
按文件名顺序依次读取
configBase
目录下面的
xml
文件部署
web
应用;
第一步,首先获取文件名(不包含
.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
是否为绝对路径,如果不是绝对路径,在改为
$CATALINA_HOME/webapps+docBase
// If external docBase, register .xml as redeploy first
if(!docBase.getCanonicalPath().startsWith(appBase().getAbsolutePath()))
{
//
这个判断很重要,这里是判断如果
docBase
路径是以
$ CATALINA_HOME/webapps+docBase
开头的字符串,则忽略掉了
isExternal = true;
...
if (docBase.getAbsolutePath().toLowerCase().endsWith(".war")) {
isWar = true;
}
} else{
// Ignore specified docBase
context.setDocBase(null);
}
从上面可以看出,
<Context path="/xxxx" docBase="xxxx" .
中
docBase
只有为绝对路径并且该路径不是以
$CATALINA_HOME/webapps
开头,才会生效;否则就忽略掉了;
2.
接下来部署
$CATALINA_HOME/webapps/
目录下以。
War
结尾的文件
deployWARs(appBase, appBase.list());
(1)
首先仍是把文件名
(
不用
.war)
作为其应用的上下文路径
;
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)
接下来判断以该上下文路径
contextPath
是否已经装载过了,如果是则直接退出;
if (deploymentExists(contextPath))
return;
(
3
)
继续判断以该上下文命名的部署文件是否存在,如
war
文件为
AAA.war,
则判断在
$CATALINA_HOME/conf/Catalina/localhost/AAA.xml
文件是否存在,如果不存在继续执行以下操作;
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
)接下来操作和上面类似,部署该
web
应用;
3.
最后是以
$CATALINA_HOME/webapps
目录下的文件夹为目标按文件夹名顺序进行部署;
deployDirectories(appBase, appBase.list());
(1)
同样先把该文件夹名作为上下文路径进行部署;
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)
接下来的步骤就基本上是一样了,首先判断该上下文路径是否已经部署过,如果是则直接退出,否则和上面一样,读取
META-INF/context.xml
文件进行部署;
注意这里和上面的
war
文件部署稍微有点不同,就是它不会
copy
部署文件
context.xml
文件到
$CATALINA_HOME/conf/Catalina/localhost
中去;