Tomcat源码解析(11)

本文深入解析Tomcat容器架构,重点介绍Host与Engine的作用及其实现原理。解释了Host容器为何必不可少,以及Engine如何管理和调度不同的Host容器。

Host和Engine

  如果你想在同一个Tomcat部署多个Context容器。需要使用Host容器。

  Context容器的父容器通常是Host容器,也可能是其他实现。或者如果不必要,就可以不使用父容器。(但是总会使用一个Host)

  Engine容器表示Catalina的整个servlet引擎。如果使用了Engine容器,它总是处于容器最顶层。添加的通常是host或者context。


Host接口

  比较重要的是map(),返回一个处理HTTP请求的Context容器。

StandardHost

  继承自ContainerBase类。实现Host和Deployer接口。

  与StandardContext和StandardWrapper类似,构造函数将一个基础阀实例添加到管道对象中。

  基础阀StandardHostValve类。

  当调用start()会添加ErrorReportValve阀与ErrorDispatcherValve阀。


每引入一个Http请求,都会调用Host实例的invoke方法。由于StandardHost没有该方法,因此调用父类ContainerBase类的invoke()->调基础阀StandardHostValve的invoke()->调StandardHost的map(),来处理请求。


StandardHostMapper类。

  ContainerBase类,会调用addDefaultMapper(),创建一个默认映射器。

  map(),只是调用了Host实例的map()。


为什么必须有一个Host容器

  若一个Context实例,使用ContextConfig对象进行设置。就必须使用一个Host对象。

  因为,使用ContextConfig对象,需要知道web.xml文件的位置。在其applicationConfig()方法中它会试图打开web.xml文件。

  URL url = servletContext.getResource(Constants.ApplicationWebXml);  

   Constants.ApplicationWebXml 的值为"/WEB-INF/web.xml" 。servletContext是applicationContext类型。

  

public URL getResource(String path){
  DirContext resources = context.getResource();
  if(resource != null){
    String fullPath = context.getName()+path;
   String hostName = context.getParent().getName();   //host不能为空
   }
}
  

Engine接口

  Engine容器也就是servlet引擎。部署Tomcat时,支持多个虚拟机的话,需要使用Engine容器。

  在Engine容器中,可以设置一个默认的Host或者Context容器。


 StandardEngine类

   作为顶层容器,子容器只能是Host容器,所以若给它设置一个非Host容器,抛出异常。

   不能有父容器,Add会抛异常


StandardEngineValve类

  是基础阀。invoke()。验证request和response类型。得到Host实例,处理该请求。invoke方法通过调Engine的map()获取host对象。调用其invoke方法。


  

Tomcat 是一个广泛使用的开源 Servlet 容器,它实现了 Java Servlet 和 JavaServer Pages (JSP) 技术。Tomcat 的内部架构设计非常模块化,这使得它既灵活又易于扩展。以下是 Tomcat 内部架构的一些关键点: ### 核心组件 Tomcat 的核心组件主要包括 **Server**、**Service**、**Connector** 和 **Container**。 - **Server** 是 Tomcat 中最顶层的组件,它可以包含多个 Service 组件。在 Tomcat 源代码中,Server 组件对应源码中的 `org.apache.catalina.core.StandardServer` 类。 - **Service** 是一个中间层组件,它将一个或多个 Connector 组件与一个 Container 组件关联起来。 - **Connector** 负责接收客户端请求,并将请求传递给 Container。Tomcat 支持多种 I/O 模型和应用层协议,例如 HTTP、HTTPS 和 AJP。 - **Container** 是处理请求的核心部分,它包含多个子容器,如 Engine、Host、Context 和 Wrapper,这些子容器负责定位并执行具体的 Servlet。 ### Connector 连接器 Connector 是 Tomcat 中处理网络通信的关键部分,它由以下几个主要组件构成: - **ProtocolHandler**:协议处理器,负责处理特定的协议,如 HTTP/1.1 或 AJP。 - **Endpoint**:端点,负责监听网络连接并接收请求。 - **Processor**:处理器,负责解析请求数据并生成相应的响应。 - **Adapter**:适配器,负责将请求从 Connector 的格式转换为 Container 可以处理的格式。 ### Container 容器 Container 是 Tomcat 中处理请求的组件,它的基本组成包括: - **Engine**:引擎,是 Container 的顶级容器,负责处理所有请求。 - **Host**:主机,表示一个虚拟主机,可以包含多个 Context。 - **Context**:上下文,代表一个 Web 应用程序。 - **Wrapper**:包装器,是最底层的容器,负责管理一个 Servlet 实例。 ### 请求处理流程 当客户端发送请求到 Tomcat 时,请求首先被 Connector 接收,然后通过 ProtocolHandler 和 Processor 解析请求,接着通过 Adapter 将请求传递给 Container。Container 通过 Mapper 组件定位到具体的 Servlet,并调用该 Servlet 来处理请求。 - **Mapper 组件**:Mapper 负责根据请求 URL 映射到相应的 Servlet。 - **定位 Servlet 流程**:Mapper 会根据请求的 URL 路径查找对应的 Context 和 Wrapper,进而找到需要执行的 Servlet。 ### 示例代码 下面是一个简单的示例代码,展示了如何使用 Tomcat 创建一个基本的 Web 应用: ```java import org.apache.catalina.startup.Tomcat; public class SimpleTomcatApp { public static void main(String[] args) throws Exception { Tomcat tomcat = new Tomcat(); tomcat.setPort(8080); // 添加一个简单的 Servlet tomcat.addWebapp("/hello", "path/to/webapp", SimpleServlet.class.getName()); // 启动 Tomcat 服务器 tomcat.start(); tomcat.getServer().await(); } } ``` 在这个示例中,我们创建了一个 Tomcat 实例,并设置了端口号为 8080。然后,我们添加了一个 Web 应用 `/hello`,并指定了一个简单的 Servlet `SimpleServlet`。最后,启动 Tomcat 服务器并等待请求。 ### 相关问题 1. Tomcat 是如何处理并发请求的? 2. 如何在 Tomcat 中配置 SSL/TLS? 3. Tomcat 中的 Session 管理是如何工作的? 4. 如何自定义 Tomcat 的 Valve 组件? 5. Tomcat 中的日志记录机制是怎样的? 以上内容结合了 Tomcat 的整体架构、核心组件以及请求处理流程,希望能够帮助理解 Tomcat 的内部实现机制和架构设计。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值