总体结构
一个Container可以选择对应多个Connector。多个Connector和一个Container就形成了一个Service,有了Service就可以对外提供服务,但是还需要Server生存环境。所以整个Tomcat的生命周期由Server控制。
Service
一个Service可以设置多个Connector,但是只能有一个Container。
所有组件的生命周期在一个Lifecycle的接口中控制。
Service接口标准实现类是StandardService,不仅实现了Service接口,还实现了Lifecycle接口,这样就可以控制下面组件的生命周期。
StandService.setContainer
先判断当前的这个Service有没有已经关联了Container,如果已经关联了,那么去掉这个关联关系——oldContainer.setService(null);如果这个oldContainer已经被启动了,则结束它的生命周期,然后再替换新的关联,再初始化并开始这个新的Container的生命周期,最后将这个过程通知感兴趣的事件监听程序。
修改Container时要将新的Container关联到每个Connector,Container和Connector没有双向关联。
addConnector
首先设置关联关系,然后初始化,开始新的生命周期。
Connector用的是数组而不是List集合,实现机制是重新创建一个当前大小的数组对象,然后将原来数组对象复制到新的数组。
Server
Server就是提供一个接口让其他程序能够访问到这个Service集合,同时维护所包含的所有Service集合的生命周期。
Lifecycle
组件的生命周期是通过Lifecycle接口来控制的,组件只要继承这个接口并实现其中的方法就可以统一被拥有它的组件控制。一层一层直到最高级的组件就可以控制Tomcat中所有组件的生命周期了。最高级的组件就是Server,控制Server的是Startup.
Lifecycle接口的方法的实现都在其他组件中,组件的生命周期由包含它的父组件控制,所以它的Start方法自然就是调用它下面组件的Start方法。
监听的代码会包围Service组件的启动过程,即简单的循环启动所有Service组件的Start方法,但是所有的Service必须实现Lifecycle接口。
Connector
Container
Container是容器的父接口,所有子容器都必须实现这个接口,Container容器使用责任链设计模式,由4个子容器组件构成,分别是Engine,Host,Context和Wrapper,Engine包含Host,Host包含Context,Context包含Wrapper。通常一个Servlet class对应一个Wrapper,如果有多个Servlet,可以定义多个Wrapper;如果有多个Wrapper,定义一个更高的Container。
Engine
Engine定义了一些基本的关联关系。没有父容器,调用setParent方法会报错。添加的子容器也只能是Host类型。
Host
Host是Engine的子容器,一个Host在Engine中代表一个虚拟主机,作用是运行多个应用,负责安装和展开这些应用,并且标识这个应用以便能够区分他们。还保存了一个主机应有的信息。
子容器是Context
Context
Context代表了Servlet的Context,具备了Servlet运行的基本环境,理论上只要有Context就能运行Servlet,简单的Tomcat可以没有Engine和Host。
Context可以管理里面的Servlet实例,在Context中是以Wrapper出现的。
Wrapper
Wrapper代表一个Servlet,负责管理一个Servlet,包括Servlet的装载,初始化,执行和资源回收。没有子容器,调用addChild将会报错。