一,容器
Tomcat中有两个核心组件:连接器和容器。连接器处理Socket通信和应用层协议的解析,得到Servlet请求。容器负责处理Servlet请求。
在Tomcat里,容器就是用来装载Servlet的。
二,容器的层次结构
Tomcat设计了4种容器,Engine,Host,Context,Wrapper。
Tomcat通过这种分层的架构,使得Servlet容器具有很好的灵活性。
1,各个容器的理解
Context表示一个Web应用程序,
Wrapper表示一个Servlet,一个Web应用程序中可能会有多个Servlet。
Host代表一个虚拟主机(或一个站点),可以给Tomcat配置多个虚拟主机地址,一个虚拟主机下可以部署多个Web应用程序。
Engine表示引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine。
2,配合server.xml配置来理解
3,Tomcat如何管理这些容器
这些容器具有父子关系,形成一个树形结构,用设计模式中的组合模式来管理这些容器。
具体实现:所有容器组件都实现Contaniner接口,这样使得Wrapper容器和 Context,Host,Engine容器的使用具有一致性。
Container接口:
public interface Container extends Lifecycle { public void setName(String name); public Container getParent(); public void setParent(Container container); public void addChild(Container child); public void removeChild(Container child); public Container findChild(String name); }
其中LifeCycle接口用来统一管理各个组件的生命周期。
三,请求定位 Servlet 的过程
1,Tomcat是如何确定请求是由哪个Wrapper容器里的Servlet来处理呢?
Tomcat通过使用Mapper组件来完成。Mapper组件的功能就是将用户请求的URL定位到一个Servlet。
原理:
Mapper组件中保存了Web应用的配置信息,容器组件和访问路径的映射关系。(Host容器中配置的域名,Context容器中的Web应用路径,以及Wrapper容器里的Servlet映射路径。)
定位过程:
当一个请求到来时,Mapper组件通过解析请求URL里的域名和路径,然后到自己保存的Map里去查找,就能定位到一个Servlet。注意:一个请求URL最后只会定位到一个Wrapper容器,也就是一个Servlet。
1.1,根据端口号选定Service和Engine
Tomcat的每个连接器都监听不同的端口(比如Tomcat默认的HTTP连接器监听8080端口),比如:URL中的端口号8080,那么这个请求会被HTTP连接器接收,因为连接器属于一个Service组件,这样Service组件就确定了。因为一个Service组件中有多个连接器和一个容器,就是Engine容器。所以Engine容器也可以确定。
1.2,根据域名确定Host
Service和Engine确定后,Mapper组件通过URL中的域名去查找相应的的Host容器。
1.3,根据URL路径找到Context组件
Host确定以后,Mapper根据URL的路径来匹配相应的Web应用的路径,即对应的Context容器
1.4,根据URL找到Wrapper(Servlet)
Context确定以后,Mapper再根据web.xml中配置的Servlet映射路径来找到具体的Wrapper和Servlet
2,除了Servlet会处理请求,在查找路径上的父子容器都会对请求做一些处理。
连接器中的Adapter会调用容器的Service方法来执行Servlet,最先拿到请求的是Engine容器,Engine容器对请求做一些处理后,会把请求传给自己自容器Host继续处理,以此类推,最后这个请求传给Wrapper容器,Wrapper会调用最终的Servlet来处理。
3,调用过程通过Pipeline-Value管道来实现
Pipeline-Value是责任链模式:
在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后再调用下一个处理者继续处理。