Tomcat源码调试环境搭好了,但是打开源码却是一头雾水,不知从哪下手,我觉得这是阅读任何项目源码刚开始都会遇到的问题,但是问题从来不可怕,下面我在Tomcat源码分析中的一些理解吧。
概念理解
谈一下对「容器」、「生命周期」、「观察者模式」这个三个概念的理解,这几个是介绍Tomcat源码和系统架构的书籍和文章中常见的概念,也是理解Tomcat设计的精髓。
- 容器
打开源码“/conf”目录下的server.xml文件,可以看到最顶层到里面依次有server、service、connector等等,这些解析之后便成为Tomcat的容器。我们姑且可以理解为管理子容器或者内部一些未知东西的工具。 - 生命周期
容器有初始化(init)、开始(start)和停止(stop)等各种状态,如何去管理一个容器从开始到结束,这应该就是生命周期管理吧,先这么简单的理解吧,认识都是一个过程,暂时也没法理解的那么全面。 - 观察者模式
不太理解的可以专门看看这个设计模式。这里可以简单理解为,把容器当做一个主题(subject),还有若干监听者(listener),容器状态的改变会触发监听者listener的一些动作等等。
关键类和接口
- Bootstrap
Tomcat源码工程巨大,但是总有一个入口,我们在启动Tomcat工程的时候,会发现项目是从Bootstrap类开始(org.apache.catalina.startup.Bootstrap.java),main方法就在这里了,到此至少知道项目是从何处开始的了。 - StandardServer
该类是对Server的具体实现,Tomcat的生命周期就是由Server掌控,Server由此是Tomcat最高级的组件,没有之一,Tomcat启动之后,首先便是Server的启动。至于Server下面的service容器暂时先不管,知道了一种容器的生命周期,其他的也就类似了。 - LifecycleBase
该类是对Lifecycle接口的实现,所有的容器都是要继承该类的,StandardServer的继承关系是:StandardServer-LifecycleMBeanBase-LifecycleBase。 - LifecycleSupport
是LifecycleBase的一个支持辅助类吧,随着容器的新建会初始化new一个,容器状态如果改变,会帮忙搞定事件触发的操作。 - LifecycleListener
上面的三个类主要跟容器有关,而这是一个监听者接口,看下面源码中的注释就可以知道了这个接口的作用的,下面是完整接口:123456789101112131415161718/*** Interface defining a listener for significant events (including "component* start" and "component stop" generated by a component that implements the* Lifecycle interface. The listener will be fired after the associated state* change has taken place.** @author Craig R. McClanahan*/public interface LifecycleListener {/*** Acknowledge the occurrence of the specified event.** @param event LifecycleEvent that has occurred*/public void lifecycleEvent(LifecycleEvent event);}
翻译一下:接口定义了一个对一些重要events感兴趣的listener,主要是那些由实现了Lifecycle接口的组件所产生的包括“start”和“stop”的events事件,这个监听者会被关联的状态触发。
生命周期管理及观察流程
StandardServer的startInternal()开始
StandardServer父类LifecycleBase中的start()方法被调用之后,紧接着StandardServer的startInternal()调用,下面是startInternal()的具体实现:
LifecycleBase的fireLifecycleEvent()方法代理
因为我自己状态改变了下,我要把消息告诉那些监听者,StandardServer调用了父类LifecycleBase的fireLifecycleEvent(),该方法代码如下:
lifecycle是这么被定义的:
思考弄一下这里的this参数是什么,说白了LifecycleSupport就是专门定义一个帮忙干活的,this就是当前的容器实例。
LifecycleSupport的fireLifecycleEvent()方法被触发
直接上代码吧:
问题已经快水落石出了,LifecycleSupport似乎是维护了listener的一个数据结构,数组,如下代码所示:
LifecycleSupport专门负责管理一些监听者(listener)的事情,比如:addLifecycleListener()、removeLifecycleListener()等等,跟listeners打交道的脏活累活最后都落到LifecycleSupport身上了。
LifecycleListener的lifecycleEvent()方法被触发
因为LifecycleListener只是一个接口,所以举一个实现类为例,如NamingContextListener类,为什么拿这个举例后面就知道了,下面就是NamingContextListener的lifecycleEvent(LifecycleEvent event)方法:
代码太长不贴那么多了,但是窥一斑可知,这里面做了很多事情,根据事件不同给出不同的处理。那么这个监听器是什么时候加入监听数组的呢?
LifecycleListener的加入
因为我们一开始就只讨论Server这个容器,那么回到刚开始的Server的实现类StandardServer这个类,观察构造方法会发现:
NamingContextListener这个listener是在容器创建之初就被放入了监听者行列,addLifecycleListener方法便是调用LifecycleBase的addLifecycleListener()这个代理方法,然后真正的脏活累活还是交给了前面交代的LifecycleSupport这个类来办。
最后
容器的生命周期和观察者模式大概就是这么回事了,后面还有一些问题需要继续思考,比如Server下面的Service到底是什么东西,Service里面的connector和container又是什么鬼,再慢慢分析吧。
-EOF-