龙空技术网

Tomcat源码分析(二):Tomcat启动流程和webapp目录下应用加载

服务端技术 695

前言:

目前朋友们对“tomcat 发布应用”可能比较珍视,兄弟们都想要了解一些“tomcat 发布应用”的相关知识。那么小编同时在网上网罗了一些对于“tomcat 发布应用””的相关资讯,希望我们能喜欢,同学们快快来学习一下吧!

一、Tomcat自身的启动脚本

tomcat的启动和关闭分别是通过执行bin目录下的startup.sh和shutdown.sh来实现的,而startup.sh和shutdown.sh里面会执行catalina.sh来完成实际的启动和关闭。在catalina.sh里面会获取或设置启动相关的环境变量,然后配置启动的各种参数,如下为启动脚本:可以看到是执行Bootstrap类。Bootstrap类在加载时,会初始化类加载器体系,主要是commonLoader,catalinaLoader,sharedLoader这三个类加载器(默认为同一个),并使用catalinaLoader来通过放射的方式加载和创建org.apache.catalina.startup.Catalina实现,最后在main方法中,根据脚本执行参数来执行启动或停止。其中启动start时,依次调用Catalina的load和start:load为加载解析conf/server.xml文件并创建StandardServer,StanderService,StandardHost对象实例,即只要server.xml中存在这些节点,则会创建对应的Container接口的实现类对象实例;start为从StanderServer开始整个Catalina容器的启动。

二、Tomcat容器启动流程

server.xml文件解析

tomcat中对xml配置文件的解析是通过Digester来完成的。xml文件的解析一般有Dom4j和SAX两种方式组成,其中Dom4j为在内存中构建一棵Dom树来解析的,而SAX则是读取输入流,然后在读到某个xml节点时,触发相应的节点事件并回调相应的处理方法来实现的。而Digester在SAX的基础上,进行了封装,使得更加方便使用,目前Digester已经是一个Apache commons子项目:DigesterCatalina的load方法的核心实现:以上代码核心方法为createStartDigester,在这个方法中定义server.xml文件的解析规则,即对每个xml节点,根据pattern定义该xml节点匹配的tomcat中的类,以及为该类对象实例填充属性对象实例。最后在digester.parse(inputSource)方法中,根据解析规则,完成对象的创建和属性值的注入。

1.简单节点解析规则定义:以Server节点为例

第一步:

第二步:

第三步:

2.复杂节点解析规则定义:通过Rule来定义复杂节点,即节点里面还包含多级节点。addRuleSet方法和addRule,其中addRule为具体添加一条解析规则。

3.HostRuleSet:定义Host节点的解析和创建Host对象实例的规则,其中addRule为该pattern匹配到的节点,在这里是Server/Service/Engine/Host,定义一条具体的解析规则,多次调用则定义多条规则,规则接口为Rule,在Rule节点的begin方法中定义具体的回调方法。

4.LifecycleListenerRule:添加监听器Listener,构造函数如下。上面那个addRule的listenerClass为:org.apache.catalina.startup.HostConfig,attributeName为:hostConfigClass,即为StanderHost对象添加了一个HostConfig到Listener列表,其中HostConfig是一个LifeCycleListener。

三、LifeCycleListener事件监听机制完成各子容器的配置解析和创建

由上分析可知在Host节点对应的StanderHost类的生命周期监听器LifeCycleListener列表,添加了一个org.apache.catalina.startup.HostConfig监听器实现。在Catalina体系的核心组件的生命周期是通过LifeCycle来管理的,即初始化,启动,停止都对应相关的状态和listener事件产生,并交给相应的监听器Listener处理。对于核心组件Host,Context的启动,分别是交给org.apache.catalina.startup包的HostConfig和ContextConfig来完成的。

1.StandardHost启动实现:startInternal

2.HostConfig的lifecycleEvent方法处理Lifecycle.START_EVENT:调用deployApps方法部署webapp目录的应用。底层实现主要为遍历docBase指定的目录,默认为webapp,然后对每个xxx.war文件,创建一个StandardContext实例,即一个应用,并添加到StandardHost的children列表中。注意这里并不进行web.xm文件的解析,只是如果在xxx.war包内存在META-INF/context.xml文件,则解析并用来填充这个StandardContext的属性。

四、webapp目录下ServletContext应用:加载与配置解析

由上可知,HostConfig底层调用deployWAR方法来遍历webapp目录,并解压war包,解析META-INF/context.xml文件,创建StandardContext对象,然后加到StandardHost的children,即子容器列表。之后在StandardHost的startInternal中遍历已经填充好的children,调用StandardContext的start方法,从而对每个Context进行启动,初始化机制也是跟StandardHost一样,使用listener事件监听机制来完成实际创建,具体为交给ContextConfig。ContextConfig:与HostConfig类似,不过是在StandardContext的startInternal方法,触发ContextConfig的lifecycleEvent方法:ContextConfig底层调用configureStart来启动应用,核心方法为webConfig。webConfig:是tomcat非常重要的一个方法,主要是根据servlet规范,解析web.xml,以及合并包含的jar包里面的web-fragment.xml文件到web.xml,获取注解信息等等工作,完成对应java servlet的ServletContext的创建,代表一个应用的配置和启动。具体在下一篇文章分析。

标签: #tomcat 发布应用