上篇文章分析了Bootstrap
类的启动流程,可以知道,Bootstrap
实际上是调用了Catalina
类的对象来实现Tomcat的启动的,这篇文章来介绍一下Catalina
类的启动流程。
回顾一下Bootstrap
中main方法执行启动时的代码:
|
|
下面介绍Catalina类中的方法。
await方法
daemon.setAwait(true);
表示该Tomcat已经执行了启动,也是调用了Catalina
中的setAwait
方法:
|
|
这里又调用的Server
的await
方法,await
方法的作用就是判断当前启动的Server所要绑定的端口(默认是8005)是否被占用,如果被占用,则会抛出以下异常:
|
|
还有一个作用就是监听Server的端口(默认是8005),会一直等待接收关闭命令,这个以后的文章会说到,这里就先不做介绍了。
load方法
Bootstrap
类中的load
方法会调用Catalina
中的load
方法,Catalina
中的load
代码如下:
|
|
该方法主要的工作是:
- 解析server.xml配置文件
- 根据server.xml文件创建对象,包括server,listener,service,connector,container等等
- 初始化上面创建的对象
server.xml文件结构
在往下看之前,还是说一下server.xml
的文件结构吧,也好参考的代码做对比,结构如下:
|
|
这里列出了大概的结构,接下来说明是解析server.xml
的流程。
createStartDigester方法
该方法负责创建一个Digester
对象,代码如下:
|
|
上面我只注释了创建Server对象的部分,其他的原理都类似,就不多说了,这里要注意一个地方:
|
|
回顾一下load
方法中的这段代码:
|
|
意思就是把当前的Catalina
对象压入栈底,然后解析配置文件。所以在Server对象创建完成后,会调用Catalina
对象的setServer方法。
这里简单介绍一下Digester
解析的原理:
- Digester实例有一个内部栈用来临时存储对象。当addObjectCreate方法实例化一个类时,就将结果放到栈中。
- 当调用两个addObjectCreate方法时,第一个对象首先放入栈中,接着是第二个对象。
- addSetNext方法用于创建两个对象之间的关系,其通过调用第一个对象指定的方法并以第二个对象作为参数传递给这个方法。
有关Digester
库的更详细的用法,请自行查找相关资料。
start方法
这里才是真正启动tomcat的代码:
|
|
await
在开头已经讨论过,就不说了。这里的getServer().start()
是负责启动server对象的,其实server对象需要做的只是启动globalNamingResources
和service
,进而会启动整个tomcat,通过上面给出的server.xml
文件的结构也可以知道,因为GlobalNamingResources
和Service
是Server
的子元素。
总结
至此,Catalina
的初始化和启动工作流程算是完成了。
由上一篇:Tomcat源码:Bootstrap启动流程和这篇文章来看,我们已经大概了解了tomcat的启动过程,所以可以总结出来tomcat的各个组件的层次关系大概如下图所示:

层次结构还算比较清晰的,接下来就是各个组件的初始化和启动的工作流程,这些流程后续有时间也会详细讨论。
睡觉。。。