Tomcat core components and source code execution flow

Tomcat directory structure

  • bin /: storage start Tomcat and stop batch script files, etc.

    • In the startup script for windows and linux are: startup.bat, startup.sh
    • shutdown.bat, shutdown.sh: for the windows and linux stop script
  • conf /: Tomcat is used to store configuration files

    • Catalina: Context used to store configuration for each virtual machine
    • context.xml: Context is used to define all the web applications are required to load the configuration, if the web application to specify their context.xml, the file will be overwritten
    • catalina.properties:Tomcat environment variable configuration
    • catalina.policy: security policy Tomcat running configuration
    • logging.propertiesTomcat configuration log file can be modified Tomcat log level and log path of the documents by
    • server.xml: Tomcat server core profile
    • tomcat-users.xml: Tomcat default user defined and role mapping configuration information
    • web.xml: Tomcat default in all applications deployment descriptor file, define the basis for the main Servlet and MIME map.
  • lib /: Tomcat server dependencies

  • logs /: Tomcat default log storage directory

  • webapps /: Tomcat default Web application deployment directory

  • work /: Web application temporary directory JSP code generation and compilation

Tomcat hierarchical representation

Here Insert Picture Description

----- Tomcat core module connector, container

Tomcat core functionality :

  • Socket connection processing, and is responsible for conversion of the byte stream object Request and Response Network.
  • Loading and managing Servlet, and specific processing request Request.

Thus the two core components designed Tomcat connector (Connector comprising at Coyote) and the container (Container comprising at Catalina) respectively to do two things. The connector is responsible for foreign exchange, the container is responsible for internal processing.
Here Insert Picture Description

Connectors - Coyote

  • Coyote is the name of the Tomcat connector frame, a Tomcat server provides an external interface for client access. Coyote client establishes connection with the server, send a request and receive a response.
  • Coyote encapsulates the underlying communication network (Socket request and response processing), provides a uniform interface Catalina vessel so that the vessel Catalina with a particular IO request protocol and completely decoupled mode of operation. Socket Coyote the Request object is input into the package, referred to Catalina processing container, after completion of processing the request, Response Coyote objects provided by Catalina writes the result into the output stream.
  • Coyote related operation as an independent module, and is only responsible for the specific protocol IO (before 8.0, Tomcat using the default I / O BIO way, then to NIO), and with no direct relationship to achieve Servlet specification, and therefore even if the Request No Response object is also achieved Servlet specification corresponding interface, but they will be further encapsulated to Catalina ServletRequest and ServletResponse.
Coyote structure

Here Insert Picture Description

  • EndPoint

    • EndPoint: Coyote communication endpoint, i.e., the communication interface monitor, receive and transmit specific Socket processor, the transport layer is an abstraction, so EndPoint to implement TCP / IP protocol.
    • Tomcat not EndPoint interface but provides an abstract class AbstractEndpoint, which defines two internal classes: Acceptor and SocketProcessor.
      • Acceptor Socket listens for connection requests.
      • Socket SocketProcessor for processing the received request, it implements Runnable interface, call processing component Processor protocol processing in the Run method. SocketProcessor be submitted to the thread pool (Executor) to perform.
  • Processor

    • Coyote 协议处理接口 ,Processor是对应用层协议的抽象,Processor用来实现HTTP协议
    • Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理
  • ProtocolHandler

    • Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协议的处理能力。Tomcat 按照协议和I/O 提供了6个实现类 :
      • AjpNioProtocol
      • AjpAprProtocol
      • AjpNio2Protocol
      • Http11NioProtocol
      • Http11Nio2Protocol
      • Http11AprProtocol
    • 配置tomcat/conf/server.xml 时 , 至少要指定具体的ProtocolHandler , 当然也可以指定协议名称, 如 : HTTP/1.1 ,如果安装了APR,那么将使用Http11AprProtocol , 否则使用 Http11NioProtocol 。
  • Adapter

    • 由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。
    • ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,不能用TomcatRequest作为参数来调用容器。
    • 连接器调用CoyoteAdapter的Sevice方法,传入的是TomcatRequest对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器的Service方法

容器 - Catalina

  • Catalina是Tomcat的servlet容器
  • Catalina包含所有的容器组件,以及安全、会话、集群、管理等Servlet 容器架构的各个方面。它通过松耦合的方式集成Coyote,以完成按照请求协议进行数据读写。同时,它还包括启动入口、Shell程序等。
  • Catalina是 Tomcat 的核心,其他模块都是为Catalina 提供支撑的。 比如 : 通过Coyote 模块提供链接通信,Jasper 模块提供JSP引擎,Naming 提供JNDI 服务,Juli 提供日志服务。
Catalina 结构

Here Insert Picture Description
说明:

  • 每个服务都包含:多个连接器组件Connector(Coyote 实现)和对应一个容器组件Container。在Tomcat 启动的时候, 会初始化一个Catalina的实例。
  • Catalina负责管理Server,而Server表示着整个服务器。Server下面有多个服务Service

Catalina 各个组件

  • Catalina:负责解析Tomcat的配置文件 , 以此来创建服务器Server组件,并根据命令来对其进行管理
  • Server:服务器表示整个Catalina Servlet容器以及其它组件,负责组装并启动Servlet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式
  • Service:服务是Server内部的组件,一个Server包含多个Service。它将若干个Connector组件绑定到一个Container(Engine)上
  • Connector:连接器,处理与客户端的通信,它负责接收客户请求,然后转给相关的容器处理,最后向客户返回响应结果
  • Container 容器,负责处理用户的servlet请求,并返回对象给web用户的模块
Container 结构

Here Insert Picture Description
各个组件

  • Engine:表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine,但是一个引擎可包含多个Host
  • Host:代表一个虚拟主机,或者一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个Context
  • Context :表示一个Web应用程序, 一个Web应用可包含多个Wrapper
  • Wrapper: 表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器
Tomcat的server.xml配置文件符合Catalina结构

Here Insert Picture Description
这些容器具有父子关系,形成一个树形结构,使用了设计模式中的组合模式,所有容器组件都实现了Container接口,组合对象是上面的Context、Host或者Engine。
Here Insert Picture Description
Container接口扩展了LifeCycle接口,LifeCycle接口用来统一管理各组件的生命周期
Here Insert Picture Description
Container通过 getParent、SetParent、addChild和removeChild等方法实现组合

Tomcat 启动流程

Here Insert Picture Description

步骤:

  • 启动tomcat , 需要调用 bin/startup.bat (在linux 目录下 , 需要调用 bin/startup.sh), 在startup.bat 脚本中, 调用了catalina.bat。
  • 在catalina.bat 脚本文件中,调用了BootStrap 中的main方法。
  • 在BootStrap 的main 方法中调用了 init 方法 , 来创建Catalina 及 初始化类加载器。
  • 在BootStrap 的main 方法中调用了 load 方法 , 在其中又调用了Catalina的load方法。
  • 在Catalina 的load 方法中 , 需要进行一些初始化的工作, 并需要构造Digester 对象, 用于解析 XML。
  • 然后在调用后续组件的初始化操作 。。。加载Tomcat的配置文件,初始化容器组件 ,监听对应的端口号, 准备接受客户端请求

总结:

  • Tomcat的启动过程非常标准化, 统一按照生命周期管理接口Lifecycle的定义进行启动
  • 首先调用init() 方法进行组件的逐级初始化操作,然后再调用start()方法进行启动
  • 每一级的组件除了完成自身的处理外,还要负责调用子组件响应的生命周期管理方法
  • 组件与组件之间是松耦合的,可以很容易的通过配置文件进行修改和替换

Tomcat 请求处理流程

Mapper组件

Tomcat用Mapper组件来确定每一个请求应该由哪个Wrapper容器里的Servlet来处理

工作原理

  • Mapper组件里保存了Web应用的配置信息(其实就是容器组件与访问路径的映射关系,比如Host容器里配置的域名、Context容器里的Web应用路径,以及Wrapper容器里Servlet映射的路径),这些配置信息就是一个多层次的Map。
  • 当一个请求到来时, Mapper组件通过解析请求URL里的域名和路径,再到自己保存的Map里去查找,就能定位到一个Servlet。一个请求URL最后只会定位到一个Wrapper容器,也就是一个Servlet

Tomcat处理请求责任链

Here Insert Picture Description

  • Tomcat中定义了PipelineValve 两个接口,Pipeline 用于构建责任链, 后者代表责任链上的每个处理器。
  • Pipiline通过获得首个Valve来启动整合链条的执行 。
  • Pipeline 中维护了一个基础的Valve,它始终位于Pipeline的末端(最后执行),封装了具体的请求处理和输出响应的过程。
  • 调用addValve()方法, 为Pipeline 添加其他的Valve, 后添加的Valve 位于基础的Valve之前,并按照添加顺序执行。

Tomcat的处理请求时序图

Here Insert Picture Description

步骤如下 :

  • Connector组件Endpoint中的Acceptor监听客户端套接字连接并接收Socket。
  • 将连接交给线程池Executor处理,开始执行请求响应任务。
  • Processor组件读取消息报文,解析请求行、请求体、请求头,封装成Request对象。
  • Mapper组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context容器、 Wrappe容器处理请求。
  • CoyoteAdaptor组件负责将Connector组件和Engine容器关联起来,把生成的Request对象和响应对象Response传递到Engine容器中,调用 Pipeline。
  • Engine容器的管道开始处理,管道中包含若干个Valve、每个Valve负责部分处理逻辑。执行完Valve后会执行基础的 Valve–StandardEngineValve,负责调用Host容器的Pipeline。
  • Host容器的管道开始处理,流程类似,最后执行 Context容器的Pipeline。
  • Context容器的管道开始处理,流程类似,最后执行 Wrapper容器的Pipeline。
  • Wrapper容器的管道开始处理,流程类似,最后执行 Wrapper容器对应的Servlet对象的处理方法。

Jasper

Jasper模块是Tomcat的JSP核心引擎,JSP本质上是一个Servlet。Tomcat使用Jasper对JSP语法进行解析,生成Servlet并生成Class字节码,用户在进行访问jsp时,会访问Servlet,最终将访问的结果接响应在浏览器端 。另外,在运行的时候,Jasper还会检测JSP文件是否修改,如果修改,则会重新编译JSP文件。

Jsp文件编译

编译后的class文件

  • 其类名为 原类名_jsp , 继承自 org.apache.jasper.runtime.HttpJspBase , 该类是HttpServlet 的子类 , 所以jsp 本质就是一个Servlet 。
  • 通过属性 _jspx_dependants 保存了当前JSP页面依赖的资源, 包含引入的外部的JSP页面、导入的标签、标签所在的jar包等,便于后续处理过程中使用(如重新编译检测,因此它以Map形式保存了每个资源的上次修改时间)。
  • 通过属性 _jspx_imports_packages 存放导入的 java 包, 默认导入 javax.servlet ,javax.servlet.http, javax.servlet.jsp 。
  • 通过属性 _jspx_imports_classes 存放导入的类, 通过import 指令导入的DateFormat 、SimpleDateFormat 、Date 都会包含在该集合中。_jspx_imports_packages 和 _jspx_imports_classes 属性主要用于配置 EL 引擎上下文。
  • 请求处理由方法 _jspService 完成 , 而在父类 HttpJspBase 中的service 方法通过模板方法模式 , 调用了子类的 _jspService 方法。
  • _jspService 方法中定义了几个重要的局部变量 : pageContext 、Session、application、config、out、page。由于整个页面的输出有 _jspService 方法完成,因此这些变量和参数会对整个JSP页面生效。 这也是我们为什么可以在JSP页面使用这些变量的原因。
  • 指定文档类型的指令 (page) 最终转换为 response.setContentType() 方法调用。
  • 对于每一行的静态内容(HTML) , 调用 out.write 输出。
  • 对于 <% … %> 中的java 代码 , 将直接转换为 Servlet 类中的代码。 如果在 Java代码中嵌入了静态文件, 则同样调用 out.write 输出。

编译流程
Here Insert Picture Description
Compiler 编译工作主要包含代码生成 和 编译两部分 :

  • 代码生成
    • Compiler 通过一个PageInfo 对象保存JSP 页面编译过程中的各种配置,这些配置可能来源于 Web 应用初始化参数, 也可能来源于JSP页面的指令配置(如 page ,include)。
    • 调用ParserController 解析指令节点, 验证其是否合法,同时将配置信息保存到PageInfo 中, 用于控制代码生成。
    • 调用ParserController 解析整个页面, 由于 JSP 是逐行解析, 所以对于每一行会创建一个具体的Node 对象。如 静态文本(TemplateText)、Java代码(Scriptlet)、定制标签(CustomTag)、Include指令(IncludeDirective)。
    • 验证除指令外其他所有节点的合法性, 如 脚本、定制标签、EL表达式等。
    • 收集除指令外其他节点的页面配置信息。
    • 编译并加载当前 JSP 页面依赖的标签
    • 对于JSP页面的EL表达式,生成对应的映射函数。
    • 生成JSP页面对应的Servlet 类源代码
  • 编译
    • 代码生成完成后, Compiler 生成 SMAP 信息。 如果配置生成 SMAP 信息,Compiler 则会在编译阶段将SMAP 信息写到class 文件中 。
    • 在编译阶段, Compiler 的两个实现 AntCompiler 和 JDTCompiler 分别调用先关框架的API 进行源代码编译。
      • 对于 AntCompiler 来说, 构造一个 Ant 的javac 的任务完成编译。
      • For JDTCompiler, calling a org.eclipse.jdt.internal.compiler.Compiler compile.

Processing requests Jsp

Tomcat in the default configuration of the web.xml a org.apache.jasper.servlet.JspServlet, for the
processing of all the requests .jsp or end .jspx, i.e. the Servlet implementation is compiled to run the inlet.
Here Insert Picture Description
JspServlet process flow diagram:
Here Insert Picture Description
compilation results

  • In tomcat / conf / web.xml configure the parameters scratchdir, the result of jsp compiled, stored in the directory.
    Here Insert Picture Description
  • If this option is not configured, it will be the results compiled, stored in the Tomcat installation directory: work / Catalina (Engine name) / localhost (Host Name) / Context name.
  • If you are using IDEA integrated development tools, visit Tomcat web project jsp, the results compiled,
    stored in: C: \ the Users \ Administrator.IntelliJIdea2019.1 \ System \ tomcat_project_tomcat \ w
    ORK \ Catalina \ localhost \ jsp_demo_01_war_exploded \ ORG \ apache \ jsp
Published 109 original articles · won praise 47 · views 30000 +

Guess you like

Origin blog.csdn.net/weixin_43934607/article/details/104385846