四、 总体的调用流程
通过init方法的例子,我们可以大概明白Tomcat的这些核心组件之间的初始化流程。其实对于Lifecycle接口的其他生命周期方法也是类似的,启动(start)、停止(stop)、销毁(destory)等方法也是这样从根节点逐级传递到叶子节点的。也同样存在对应的startInternal()、stopInternal()、destroyInternal()方法。
当然,并不是每个组件都会重写这些实际的生命周期方法 XXXInternal(), 比如 StandardHost就没有重写 initInternal()方法,但重写了startInternal()方法。 这完全由按照逻辑需要决定,反过来说,这也给后期逻辑扩展预留了位置。
所以,对于Tomcat的启动停止等操作,实际上逻辑是这样的:
(图四)
五、 Bootstrap、Catalina与组件的生命周期方法的对应关系
用户对Tomcat发出Start、Stop等指令,Tomcat的Bootstrap中的main方法接到对应的指令参数后,通过反射方式调用Catalina的对应方法,再由Catalina调用Server的对应方法。至此,这个核心组件树由根部开始逐步调用下一级的对应方法,直至叶子节点。
用户指令参数、Catalina的方法以及核心组件的生命周期方法的对应关系如下图:
(图五)
总结
通过本文我们总览了核心组件之间的关系以及逐级调用的逻辑。也以此为例学习了一个设计模式:模板方法模式。
思考:设计模式之间经常关联使用,在这个例子里,还用到了什么设计模式或者原则呢?