关于java:学习Tomcat五之Context和Wrapper容器

9次阅读

共计 3324 个字符,预计需要花费 9 分钟才能阅读完成。

后面的文章中,咱们介绍了 Tomcat 的 Engine 和 Host 容器,咱们晓得一个 Tomcat 最多只有一个 Engine 容器,一个 Engine 容器能够蕴含多个 Host 容器,申请中的不同的 Host 对应不必的 Host 容器。本章咱们会介绍 Tomcat 的另外两个容器:Context 容器和 Wrapper 容器。一个 Host 容器能够蕴含多个 Context 容器:同一个 Host 上面能够蕴含多个利用,每个利用对应一个 Context 容器。一个 Context 容器又能够蕴含多个 Wrapper 容器:每个 Wrapper 容器蕴含一个 Servlet 容器,意味着 Tomcat 容许一个利用有多个 servlet 实现。

Tomcat 申请流程

咱们当初晓得 Tomcat 最重要的组件是连接器和四种类型的容器,上面的图展现了 Tomcat 的一次申请是如何在连接器和四种容器之间流转的,假如 Http 申请头为 ”GET /appB/servletB/some-url HTTP/1.1 Host: www.krishnan.com”,当申请拜访到 Tomcat 容器时,会通过以下流转步骤:

  1. Tomcat 的连接器监听 SocketServer,发现这个申请,依照指定的协定和 IO 形式解决申请 Socket 音讯,解析 Socket 为对应的 Request 实体,并提供回写报文的 Response 实体。
  2. 连接器将 Request/Response 交给 Engine 容器,Engine 容器存储了申请域名和 Host 容器之间的映射关系。比方 ”www.krishnan.com” 域名对应于 krishnan_webapps Host 容器。
  3. Engine 容器将申请交给对应的 Host 容器,Host 容器开始解析申请中的门路,如果配置了门路和利用之间的关系,比方 ”/appB” 对应于 appB Context 容器,Host 容器会装置配置将申请交给对应利用的 Context 容器。
  4. Host 容器解析门路并将利用交给 Context 容器之后,如果一个利用有多个 Servlet,那么这个利用的 Context 容器也会蕴含多个 Wrapper 容器,咱们能够通过门路来将不同的申请映射到不同的 Servlet 容器。比方图中的 ”/servletB” 对应 servletB Wrapper 容器,Context 容器将申请交给 Wrapper 容器。
  5. Context 容器依照门路将申请交给对应的 Wrapper 容器,Wrapper 容器会加载对应的 Servlet 实现类,调用 servlet 实现类中的逻辑解决 Request 并将处理结果写入 Response 中。

Context 容器

咱们在配置 Tomcat 应用程序的时候,总是须要配置一个 web.xml 文件,这个文件就是 Context 容器去解析的。tomcat 默认的 web.xml 的配置如下所示,该配置中配置了两个 WrapperContext,别离对应于两个 Servlet 配置。在 web.xml 中,咱们常常能够看到 listener 标签,次要是用于监听 Context 容器的申明周期事件。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"version="5.0">
  <request-character-encoding>UTF-8</request-character-encoding>
  <response-character-encoding>UTF-8</response-character-encoding>
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

Wrapper 容器

Wrapper 容器是最小的容器,每个 Wrapper 都能够对应一个 Servlet 的实例。当申请转发到 Wrapper 容器之后,wrapper 容器在调用 Pipeline 办法之后,会应用特定的类加载器去加载 servlet 类,对 servlet 进行实例化和初始化,而后将申请交给 servelt 的 service 办法进行解决。

咱们常见的 Spring 的 DispatchServlet 是线程平安的,所以 Tomcat 不须要保障 Servlet 的并发平安。对于非线程平安的 servlet,则能够通过 SingleThreadModel 来保障多申请下 servlet 的失常运行。

Wrapper 容器的次要作用就是载入 servlet 类并进行实例化,并调用 service 办法。当第一次申请某个 servlet 类的时候,Wrapper 容器会载入 servlet 类。Tomcat 提供了专门的类加载器用于加载 servlet,对于这个类加载器我会在我的其它文章中介绍。

Wrapper 容器的根本阀门 StandardWrapperValve 还会在调用 servelt 容器之前调用用户配置的过滤器链 Filter。

我是御狐神,欢送大家关注我的微信公众号:wzm2zsd

本文最先公布至微信公众号,版权所有,禁止转载!

正文完
 0