后面的文章中,咱们介绍了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容器时,会通过以下流转步骤:
- Tomcat的连接器监听SocketServer,发现这个申请,依照指定的协定和IO形式解决申请Socket音讯,解析Socket为对应的Request实体,并提供回写报文的Response实体。
- 连接器将Request/Response交给Engine容器,Engine容器存储了申请域名和Host容器之间的映射关系。比方"www.krishnan.com"域名对应于krishnan_webapps Host容器。
- Engine容器将申请交给对应的Host容器,Host容器开始解析申请中的门路,如果配置了门路和利用之间的关系,比方"/appB"对应于appB Context容器,Host容器会装置配置将申请交给对应利用的Context容器。
- Host容器解析门路并将利用交给Context容器之后,如果一个利用有多个Servlet,那么这个利用的Context容器也会蕴含多个Wrapper容器,咱们能够通过门路来将不同的申请映射到不同的Servlet容器。比方图中的"/servletB"对应servletB Wrapper容器,Context容器将申请交给Wrapper容器。
- 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
本文最先公布至微信公众号,版权所有,禁止转载!