0%

tomcat之Container容器

Tomcat 之 Container 容器深度解析

在 Tomcat 架构中,Container(容器) 是负责处理内部请求、封装 Servlet 并管理其生命周期的核心组件。与连接器(Connector)负责对外通信不同,容器专注于请求的内部处理流程。本文将详细解析 Container 容器的层级结构、核心接口及工作机制。

Container 容器的层级结构

Container 是一个接口,其下分为四个子接口,形成层级化的容器结构,从上到下依次为:

  • Engine:最顶层容器,代表整个 Servlet 引擎
  • Host:表示一个虚拟主机(站点)
  • Context:表示一个 Web 应用程序
  • Wrapper:表示一个具体的 Servlet

它们的装配关系为:
Engine → Host(多个) → Context(多个) → Wrapper(多个)

核心接口解析

1. 顶层接口 Container

Container 接口定义了所有容器的通用行为,包括父子容器管理、生命周期控制等。核心方法如下:

方法 功能描述
getPipeline() 获取当前容器的 Pipeline(用于管理 Valve 拦截器)
getName()/setName() 获取 / 设置容器名称(同一父容器下名称唯一)
getParent()/setParent() 获取 / 设置父容器
addChild()/removeChild() 添加 / 移除子容器
getRealm() 获取关联的安全域(用于身份验证)

核心特性

  • 所有容器都必须实现 Lifecycle 接口,支持生命周期管理(启动、停止等)。
  • 通过 Pipeline 机制实现请求处理的拦截与增强(类似过滤器链)。

2. Engine 容器

Engine 是最顶层的容器,代表整个 Servlet 引擎,一个 Service 中最多只能有一个 Engine。

核心接口方法:
  • getDefaultHost():获取默认虚拟主机名称(当请求的域名无法匹配时使用)
  • setJvmRoute():设置 JVM 路由 ID(用于集群环境区分节点)
  • getService():获取关联的 Service 组件
实现类:StandardEngine
  • 父容器为 null(最顶层),子容器只能是 Host。
  • 主要作用:接收连接器的请求,根据域名路由到对应的 Host 容器。

3. Host 容器

Host 代表一个虚拟主机(站点),与域名关联(如 localhostexample.com),负责管理多个 Web 应用(Context)。

核心接口方法:
  • getAppBase():获取应用部署目录(如 webapps
  • setAutoDeploy():设置是否自动部署目录下的应用
  • addAlias():添加域名别名(如 www.example.com 映射到 example.com
  • findAliases():获取所有别名
实现类:StandardHost
  • 父容器必须是 Engine,子容器只能是 Context。
  • 功能:管理应用的部署、启动和卸载,支持 WAR 包自动解压。

4. Context 容器

Context 代表一个 Web 应用程序(对应 Servlet 规范中的 ServletContext),管理多个 Servlet(Wrapper)。

核心接口方法:
  • getDocBase():获取应用的文档根目录(如 /WEB-INF
  • setPath():设置应用的上下文路径(如 /myapp
  • addServletMapping():添加 URL 路径与 Servlet 的映射
  • getSessionTimeout():获取默认会话超时时间(分钟)
  • reload():重新加载应用(用于热部署)
实现类:StandardContext
  • 父容器必须是 Host,子容器只能是 Wrapper。
  • 核心功能:管理 Servlet 上下文、过滤器、监听器及资源文件。

5. Wrapper 容器

Wrapper 是最底层的容器,代表一个具体的 Servlet,负责其生命周期管理。

核心接口方法:
  • getServletClass():获取 Servlet 类的全限定名
  • load():加载并初始化 Servlet(调用 init() 方法)
  • allocate():分配一个初始化后的 Servlet 实例(支持单线程模型)
  • addInitParameter():添加 Servlet 初始化参数
  • unload():卸载 Servlet(调用 destroy() 方法)
实现类:StandardWrapper
  • 父容器必须是 Context,无子容器
  • 注意:Wrapper 不直接调用 service() 方法,而是通过 StandardWrapperValve 拦截器触发。

容器配置实例

Tomcat 的容器结构可通过 conf/server.xml 配置,示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<!-- 连接器:处理HTTP请求 -->
<Connector port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

<!-- Engine容器:顶层引擎 -->
<Engine name="Catalina" defaultHost="localhost">

<!-- Host容器:虚拟主机localhost -->
<Host name="localhost" appBase="webapps" autoDeploy="true">

<!-- Context容器:Web应用myapp -->
<Context path="/myapp" docBase="myapp" reloadable="true"/>

</Host>
</Engine>
</Service>
</Server>
  • Context 配置方式
  1. server.xml 中直接定义 <Context> 标签
    1. conf/[Engine名]/[Host名]/ 目录下创建 XML 文件
  2. 应用内的 META-INF/context.xml(优先级最高)

请求定位 Servlet 的流程

当请求到达 Tomcat 后,容器通过以下步骤定位到目标 Servlet:

  1. 确定 Engine:根据请求的协议和端口匹配对应的 Service 和 Engine。
  2. 确定 Host:根据请求的域名(如 localhost)匹配对应的 Host 容器。
  3. 确定 Context:根据 URL 路径(如 /myapp)匹配对应的 Web 应用。
  4. 确定 Wrapper:根据 URL 路径(如 /myapp/login)匹配对应的 Servlet。

例如,请求 http://localhost:8080/myapp/login 的定位流程:
Engine(Catalina) → Host(localhost) → Context(/myapp) → Wrapper(LoginServlet)

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10