本文主要讲解Tomcat启动和部署webapp时的原理和过程,以及其使用的配置文件的详解。主要有三大部分:
1.Tomcat的简介和启动过程
2.Tomcat部署webapp
3.Tomcat处理一个http请求的过程
【简介】
Tomcat依赖/conf/server.xml这个配置文件启动server(一个Tomcat实例,核心就是启动容器Catalina)。
Tomcat部署Webapp时,依赖context.xml和web.xml(/conf/目录下的context.xml和web.xml在部署任何webapp时都会启动,他们定义一些默认行为,而具体每个webapp的 META-INF/context.xml 和 WEB-INF/web.xml 则定义了每个webapp特定的行为)两个配置文件部署web应用。
第一部分、Tomcat的简介和启动过程
一个标准TOMCAT结构目录如上图所示:
BIN目录主要存放各种平台下启动和关闭Tomcat的脚本文件.其中 有个档是catalina.bat,打开这个windos配置文件,在非注释行加入JDK路径,例如 : SET JAVA_HOME=C:\j2sdk1.4.2_06 保存后,就配置好tomcat环境了. startup.bat是windows下启动tomcat的文件,shutdown.bat是关闭tomcat的文件.
conf:存放不同的配置文件(如:server.xml和web.xml);
server.xml文件:该文件用于配置和server相关的信息,比如tomcat启动的端口号、配置host主机、配置Context
web.xml文件:部署描述文件,这个web.xml中描述了一些默认的servlet,部署每个webapp时,都会调用这个文件,配置该web应用的默认servlet。
tomcat-users.xml文件:配置tomcat的用户密码与权限。
context.xml:定义web应用的默认行为。
/lib:存放Tomcat运行需要的库文件(JARS);
/logs:存放Tomcat执行时的LOG文件;
/temp: 临时目录
/webapps:Tomcat的主要Web发布目录(包括应用程序示例);
/work:存放jsp编译成Servlet后产生的class文件;
二、Tomcat启动过程
1、开启Tomcat:可以在IDE中启动Tomcat的服务器,也可以手动在/bin/目录下找到startup.bat并双击,然后程序就会依次执行以下步骤:
(1)引导(Bootstrap)启动:调用了org.apache.catalina.startup.Bootstrap.class中的main方法,开始启动Tomcat容器;main方法如下:
publicstaticvoid main(String args[]) {
if(daemon ==null) {
daemon =newBootstrap();//创建了一个引导对象try{//引导对象初始化,即创建了Catalina容器 daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}
// 根据不同的命令参数执行try {
String command = "start";
if(args.length > 0) {
command = args[args.length - 1];
}
if(command.equals("startd")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} elseif(command.equals("stopd")) {
args[args.length - 1] = "stop";
daemon.stop();
} elseif(command.equals("start")) {
daemon.setAwait(true);
daemon.load(args);
daemon.start();
} elseif(command.equals("stop")) {
daemon.stopServer(args);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}
}publicvoid init()
throws Exception
{
// Set Catalina path
// 设置catalina_home属性,tomcat启动脚本里有通过-Dcatalina.home设置 setCatalinaHome();
// 设置catalina_base属性,运行多实例的时候该目录与catalina_home不同 setCatalinaBase();
// 初始化classloader,读取conf/catalina.properties,根据指定的repository创建classloader
// 有三个classloader 分别是common、catalina、shared,tomcat6中三个相同 initClassLoaders();
// 设置当前线程的classloader Thread.currentThread().setContextClassLoader(catalinaLoader);
// 待研究 SecurityClassLoad.securityClassLoad(catalinaLoader);
// 以下通过反射调用Catalina中的方法
// Load our startup class and call its process() method if (log.isDebugEnabled())
log.debug("Loading startup class");
Class startupClass =
catalinaLoader.loadClass
("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();
// Set the shared extensions class loader if (log.isDebugEnabled())
log.debug("Setting startup class properties");
String methodName = "setParentClassLoader";
Class paramTypes[] =newClass[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] =newObject[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
2)调用Bootstrap中的init(),创建了Catalina对象(核心容器):主要进行了以下三步:
//设置tomcat实例的环境变量
① Set up the environment variables required by this Tomcat instance
//实例化将用于运行Tomcat实例的通用类加载
② Instantiate the general class loaders that will be used for our running Tomcat instance
//初始化tomcat实例
③ Initialize this Tomcat instance
(3)调用Bootstrap中的load():实际上是通过反射调用了catalina的load方法。
①Parse the main configuration file for a Tomcat instance, server.xml, converting each configuration element into the appropriate Tomcat component1。(找到config file(server.xml);然后创建digester,解析server.xml,生成各组件对象(Server、Service、Container、Connector等)以及建立相互之间的关系。 )
(4)Start up our outermost Top Level Element—the Server instance。(最后start(),同样是在Bootstrap中通过反射调用catalina对象的start方法。接着启动server.start()方法:((Lifecycle) getServer()).start(); 接着调用service.start()方法。接下来是一系列的container的start,后续在分析(会部署所有的项目)
三、server.xml配置简介: 下面讲述这个文件中的基本配置信息,更具体的配置信息请参考tomcat的文档