近来,我开始阅读tomcat的源码,感觉还挺清晰易懂;为了方便理解,我参考了网上的一些文章,把tomcat的组成归纳一下;整个tomcat的组成如下图所示:
Tomcat在接收到用户请求时,将会通过以上组件的协作来给最终用户产生响应。首先是最外层的Server和Service来提供整个运行环境的基础设施,而Connector通过指定的协议和接口来监听用户的请求,在对请求进行必要的处理和解析后将请求的内容传递给对应的容器,经过容器一层层的处理后,生成最终的响应信息,返回给客户端。
Tomcat的容器通过实现一系列的接口,来统一处理一些生命周期相关的操作,而Engine、Host、Context等容器通过实现Container接口来完成处理请求时统一的模式,具体表现为该类容器内部均有一个Pipeline结构,实际的业务处理都是通过在Pipeline上添加Valve来实现,这样就充分保证整个架构的高度可扩展性。Tomcat核心组件的类图如下图所示:
接着,以tomcat的入口为起点,我将初始化的步骤描述在以下流程图中:
Tomcat在启动时的重点功能如下:
1、初始化类加载器:主要初始化CommonLoader、CatalinaLoader以及SharedLoader;
2、解析配置文件:使用Digester组件解析Tomcat的server.xml,初始化各个组件(包含各个web应用,解析对应的web.xml进行初始化);
3、初始化连接器:初始化声明的Connector,以指定的协议打开端口,等待请求。
各个类职责(翻译自tomcat6源码注释)
1、Bootstrap
Catalina的Boostrap加载器。此应用程序构建了一个类加载器用于加载的Catalina自身的类(在“catalina.home”中的“服务器”目录下的所有JAR文件),并开始定期执行的容器。这种迂回的方法的目的是保持Catalina自身的类(和它们所依赖的任何其他类,如XML解析器)的系统类路径中,所以无法看到应用级的类。
2、Catalina
Startup/Shutdown shell
3、StandarServer
Server接口的标准实现,当deploy和start时可用(但不是必须)
4、StandarService
Service接口的标准实现,关联的Container是Engine的实例,但不是必须
5、Container
Container是从client中执行接收请求,而且基于这些请求返回响应。一个Container能选择地支持一个处理请求的顺序在运行时配置,通过实现Pipeline接口。
5-1、Context
一个上下文是一个容器,它代表了一个servlet上下文,因此一个单独的Web应用程序中的Catalina servlet引擎。它是应用于几乎每一个部署的Catalina(即使连接到一个网络服务器(如Apache)的连接器使用Web服务器的设施,以确定在适当的包装处理此请求。它也提供了一个方便的机制,以使用拦截器,看到这个特定的web应用程序处理每一个请求。
附加到一个上下文的父容器通常是一个Host,但可能有一些其他的实施,或者,如果不是必要的,也可以省略。
连接上下文的子容器包装(即单独的servlet定义)实现。
5-2、Engine
引擎是一个容器,它代表整个Catalina servlet引擎。它是非常有用的方案在以下类型:
*您希望使用拦截器,看到整个engine的每一个请求处理
*您希望运行的Catalina在一个独立的HTTP连接器,但是还是要支持多个虚拟主机。
一般情况下,您将不能使用的引擎时,部署Catalina连接到一个网络服务器(如Apache),因为连接器将已使用的Web服务器的设备,以确定哪些上下文(或也许甚至它的包装)应该被利用来处理这个的要求。子容器连接到Engine的主机(虚拟主机)或Context(即个人单独的servlet上下文)的实现,取决于Engine的执行。
如果使用,Engine始终在Catalina层次结构的顶层容器。因此,实现的setParent()方法抛出IllegalArgumentException。
5-3、Wrapper
一个Wrapper是一个容器,它代表一个单独的servlet定义的Web应用程序的部署描述符。它提供了一个方便的机制来使用拦截器,每一个请求由这个定义的servlet。
实现Wrapper是负责管理servlet的生命周期,以及其基本的servlet类,包括调用init()和destroy()在适当的时候尊重了SingleThreadModel声明的servlet类本身的存在。
6、Connector
Coyote connector的实现
7、Adapter
表示一个coyote基于servlet容器中的入口点
8、ProtocolHandler
protocol实现的抽象,包括线程,处理器是单线程的,基于流的协议,将不适合JK协议,如JNI;这是coyoute connector实现的主接口;Adapter是coyote servlet container的主接口。
转自http://blog.csdn.net/xiejueheng/article/details/45799501