总体架构
核心功能:
- 处理socket连接,负责将网络字节流与Request和Response对象的转化;
- 加载和管理Servlet,以及具体处理Request请求。
Tomcat支持的io模型有: NIO、NIO2、APR Tomcat支持的应用层协议有: http1.1 ajp http2.0
tomcat最顶层是server,一个server有多个service,一个service有多个连接器和一个容器,连接器和容器之间通过ServletRequest和ServletResponse通信。
通过组合模式、模板方法、观察者模式和骨架抽象类,tomcat定义了基类LifeCycleBean实现LifeCycle接口,把公共的逻辑,生命周期状态转变和维护、生命事件的触发和监听器的添加删除,子类负责实现自己的init、stop和start等方法。
- tomcat自定义了监听器
- @WebListener注解,定义自己的监听器
StandardServer、StandardService 等是 Server 和 Service 组件的具体实现类,它们都继承了 LifecycleBase。
StandardEngine、StandardHost、StandardContext 和 StandardWrapper 是相应容器组件的具体实现类,因为它们都是容器,所以继承了 ContainerBase 抽象基类,而 ContainerBase 实现了 Container 接口,也继承了 LifecycleBase 类,它们的生命周期管理接口和功能接口是分开的。
连接器Connector
连接器进一步细化:
- 监听网络端口
- 接受网络请求
- 读取网络字节流
- 根据应用层协议解析字节流,生成统一的tomcat request和tomcat response对象
- 将tomcat request对象转成servletRequest
- 调用servlet容器,得到servletResponse
- 将servletResponse转成tomcat response
- 将tomcat response转成网络字节流
- 将响应字节流写回给浏览器
按照高内聚的功能划分:
- 网络通信
- 应用层协议解析
- tomcat request/response与servlet request/response的转换
组件通过接口交互,好处是封装变化。
Endpoint负责提供字节流给Processor,Processor负责提供tomcat request对象给Adapter,Adapter负责提供Servlet Request给容器。
其中Endpoint和Processor抽象组装在一起形成了ProtocolHandler组件。
ProtocolHandler
Endpoint
接口,抽象实现类是AbstractEndpoint,具体子类在NioEndpoint和Nio2Endpoint,其中两个重要组件:Acceptor和SocketProcessor。
Acceptor用于监听Socket连接请求,SocketProcessor用于处理收到的Socket请求,提交到线程池Executor处理。
Processor
接收Endpoint的socket,读取字节流解析成tomcat request和response,通过adapter将其提交到容器处理。
Processor的具体实现类AjpProcessor、Http11Processor实现了特定协议的解析方法和请求处理方式。
Endpoint接收到socket连接后,生成一个socketProcessor交给线程池处理,run方法会调用Processor解析应用层协议,生成tomcat request后,调用adapter的service方法。
Adapter
ProtocolHandler接口负责解析请求生成tomcat requst,CoyoteAdapter的service方法,将Tomcat Request对象,转成ServletRequest,再调用service方法。
容器Container
容器的层次结构
父子关系的Engine、Host、Context、Wrapper和Servlet。 Context表示web应用程序、wrapper表示servlet、context有多个wrapper,host也有多个context。
Host 代表的是一个虚拟主机,或者说一个站点,可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可以部署多个 Web 应用程序;Engine 表示引擎,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine。
容器通过Pipeline-Valve责任链,对请求一次处理,invoke处理方法,
每个容器都有一个Pipeline,触发第一个Valve,这个容器的valve都会被调到,不同容器之间通过Pipeline的getBasic方法,负责调用下层容器的第一个Valve。
整个调用连由连接器中的adapter触发,调用engine中的第一个Valve。
// Calling the container
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
wrapper容器的最后一个valve创建一个filter链,并调用doFilter方法,最终会调用到servlet的service方法。
final class StandardWrapperValve
extends ValveBase {
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// ...
ApplicationFilterChain filterChain =
ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
// Call the filter chain for this request
// NOTE: This also calls the servlet's service() method
Container container = this.container;
try {
if ((servlet != null) && (filterChain != null)) {
// Swallow output if needed
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
// dofilter
filterChain.doFilter(request.getRequest(),
response.getResponse());
}
} finally {
String log = SystemLogHandler.stopCapture();
if (log != null && log.length() > 0) {
context.getLogger().info(log);
}
}
} else {
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
// dofilter
filterChain.doFilter
(request.getRequest(), response.getResponse());
}
}
}
} catch() {
// ...
}
}
}
ServletContext是tomcat中的一个成员变量,spring中的ApplicationContext是servlet规范中的ServletContext属性。