tomcat启动过程分析

1、通过catalina.sh start脚本启动,调用org.apache.catalina.startup.Bootstrap的main方法,传人参数start,首先是创建一个Bootstrap的实例并付给static变量daemon,然后调用daemon的init方法,在init方法中设置catalina-home,catalina-base,之后根据catalina.properties的配置创建commonLoader(父loader为空)、catalinaLoader、sharedLoader(server.loader,shared.loader默认为空,此时,catalinaLoader、sharedLoader使用其父loader即commonLoader),将catalinaLoader设为当前线程的上下文classloader,如果设置了SecurityManager,则preload一些class文件,然后调用catalinaLoader加载org.apache.catalina.startup.Catalina,并初始化一个实例startupInstance,赋值给catalinaDaemon,通过反射调用startupInstance的setParentClassLoader方法,将ParentClassLoader设置为sharedLoader。然后调用daemon的load方法,通过反射调用catalinaDaemon的load方法。最后调用daemon的start方法,通过反射调用catalinaDaemon的start方法。

2、catalina的load方法

首先初始化catalina-home等dir,初始化naming,然后创建digester,用来读取conf/server.xml配置文件,创建server、service等组件。

initDirs();

// Before digester - it may be needed

initNaming();

// Create and execute our Digester
Digester digester = createStartDigester();

InputSource inputSource = null;
InputStream inputStream = null;
File file = null;
try {
  file = configFile();
  inputStream = new FileInputStream(file);
  inputSource = new InputSource("file://" + file.getAbsolutePath());
} catch (Exception e) {
  ;
}

tomcat初始化组件server、service、engine、host、context等,并设置包含关系的过程是通过开源的digester库来完成的,根据配置文件conf/server.xml中配置的信息来初始化各个组件,而不是通过硬编码的方式(配置有改动之后需要重新编译),提供了极大的灵活性。

在调用digester的parse方法处理xml之前,需要制定一系列的规则,例如遇到server、service元素时需要采取什么动作,做哪些关联等。例如:

digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer",  "className");

digester.addSetProperties("Server");

digester.addSetNext("Server", "setServer", "org.apache.catalina.Server");

上面的三条规则的第一个参数都是patten,即指定遇到这个server标签时采取的动作:

第一条当遇到Server标签时,创建一个server对象,如果没有制定className属性的话,则默认创建org.apache.catalina.core.StandardServer类的实例,否则根据制定的className属性来创建server,并压人digester的栈中;

第二条addSetProperties将digester的栈顶元素(即刚压人的server实例)出栈,并根据xml中配置的属性调用相应方法给server实例进行设置;

第三条addSetNext将栈顶的2个元素出栈,假设第一个出栈为a,第二个为b,则调用b的setServer方法,参数是a,而且a的Type为org.apache.catalina.Server。

这里有个问题,Server是server.xml的顶层标签,当遇到第一条规则的时候只向栈里压了一个元素,第三条规则要求出栈2个元素,栈底是哪个元素?

在load方法创建digester之后,调用parse之前,还压人了一个元素,代码如下:

digester.push(this);

digester.parse(inputSource);

即把Catalina实例本身压人栈中,Catalina继承了Embedded,Embedded又继承了StandardService,看见Catalina是一个service,这样就把Catalina的server变量指向了堆栈中的server实例。

由于server和service是一对多的关系,通过server.xml可以配置server标签包含service标签,即server指向service,而反向关系需要通过上述规则进行设置。

3、catalina的start方法

// Start the new server

if (getServer() instanceof Lifecycle) {

try {

((Lifecycle) getServer()).start();

} catch (LifecycleException e) {

log.error("Catalina.start: ", e);

}

}

getServer即第2步中通过第三条获得的Server实例,调用其start方法,将依次调用其组件的start方法。

之后设置退出钩子,当用户关闭tomcat窗口或者杀死进程时,启动CatalinaShutdownHook线程,调用stop方法。

if (shutdownHook == null) {

shutdownHook = new CatalinaShutdownHook();

}

Runtime.getRuntime().addShutdownHook(shutdownHook);

然后主线程进入等待状态,监听8005端口,如果收到“SHUTDOWN”命令则退出。

tomcat启动过程分析

时间: 2024-10-05 14:11:38

tomcat启动过程分析的相关文章

Tomcat 学习进阶历程之Tomcat启动过程分析

本节通过跟踪Tomcat的源码来分析Tomcat是如何启动及装配各个组件的.最好下载Tomcat的源码导入到Eclipse,这样方便跟踪.方法可参考: http://www.cnblogs.com/huangfox/archive/2011/10/20/2218970.html 在Tomcat的启动脚本篇,我们分析过,当执行Start.bat文件时,最后实际调用的是BootStrap.java类.如下图: 如上图,实际调用BootStrap,并传递一个名为'start'参数. 在BootStra

Tomcat启动分析(一)

当我们在Linux下启动tomcat的时候,通过ps查看其进程信息为,接下来的内容我们就以此进行分析: [[email protected] ~]$ ps -ef |grep java tomcat 1521 1 18 23:20 tty1 00:00:09 /usr/bin/java -Djava.util.logging.config.file=/home/tomcat/apache-tomcat-7.0.69/conf/logging.properties -Djava.util.logg

Tomcat源码解析-启动过程分析之主干流程

Tomcat启动入口就在脚本startup.sh中,具体脚本可以看tomcat的源码,这个启动脚本主要用来判断环境,找到catalina.sh脚本路径,将启动参数传递给catalina.sh执行.catalina.sh start 最终会执行org.apache.catalina.startup.Bootstrap中的main方法,并把start参数传入.以后分析Tomcat关闭的时候,也是一个套路,最终都会调用到org.apache.catalina.startup.Bootstrap的mai

Tomcat探秘(4):tomcat启动过程详述

熟悉Tomcat的工程师们,或者从事Java开发的,肯定都知道Tomcat是如何启动和停止的.在Tomcat源码包里面有个bin目录,该目录下放置了一些很重要的脚本,Tomcat启动和停止的脚本程序就放在这里,分别是startup.bat.shutdown.bat(Windows环境)和start.sh.shutdown.sh(Linux.Unix环境).大家一定都知道如何使用它们,接下来就是研究一下它们是如何实现启动和停止服务的. 在实际的生产环境下,绝大多数的Tomcat都是部署在Linux

Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

原文:http://www.cnblogs.com/heshan664754022/archive/2013/03/27/2984357.html Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量) 用文本编辑工具打开用于启动Tomcat的批处理文件startup.bat,仔细阅读.在这个文件中,首先判断CATALINA_HOME环境变量是否为空,如果为空,就将当前目录设为CATALINA_HOME的值.接着判断当前目录下是否存在bin\catalina.bat,如果文件

eclipse中配置的tomcat 启动正常 但是访问报404错误

问题描述: 在eclipse中配置的Tomcat,启动是正常的,控制台显示启动成功,也没有报任何错误信息,但是访问的时候就报404错误,然后直接在bin目录下启动startup.bat的方式就是正常的.然后就很纳闷,之后在网上搜了下资料,说是Eclipse的配置出了问题. 解决方案: 1.如果Server里的tomcat启动了,需要先停掉.然后再移除添加的项目 2.之后双击server中配置的tomcat服务器,会弹出如下界面. 3.在Server Locations配置中选择第二个选项,use

tomcat启动闪退

TOMCAT启动时报错:the CATALINA_HOME environment variable is not defined correctly 运行tomcat/bin目录下的startup.bat时报错:the CATALINA_HOME environment variable is not defined correctly 碰到这个问题时的第一反应是添加CATALINA_HOME环境变量: 添加环境变量后发现问题不能解决,还是报同样的错误,打开startup.bat脚本,找到出错

Tomcat启动报错[org.apache.struts2.dispatcher.Dispatcher]Dispatcher initialization failed

Tomcat启动报错: [org.apache.struts2.dispatcher.Dispatcher]Dispatcher initialization failed Unable to load configuration. - bean - jar:file:/E:/SoftwareDevelopment/Software/Eclipse4.3/eclipse-jee-kepler-SR1-win32-x86_64/Workspace/.metadata/.plugins/org.ec

Tomcat启动报错 Failed to start component [StandardServer[8005]]解决

SEVERE: The required Server component failed to start so Tomcat is unable to start. org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]] 之前在Eclipse上部署了Tomcat服务器,今天在MyEclipse上部署,结果Tomcat启动失败,报错.在网上搜了半天,有的说是因为端口被占用,有