简述
在第一章开始就提到,Tomcat的本质什么?是容器。容器这个概念现在很火,一提到容器,我们立马可以想到虚拟化,SAAS,Docket。虽然在这里,我们不会深入去探究其他虚拟化相关技术中的容器思想,但Tomcat的容器究竟是什么,容器为Tomcat带来了什么,这次我们一起去探究。
本篇单独作为DEMO运行意义不大,因此和下一篇合并提供DEMO
Container
org.apache.catalina.Container 接口定义了容器的形式,有四种容器:
Name | Lifecycle |
---|---|
Wrapper | 底层容器,servlet运行容器,每个wrapper运行一个servlet |
Conetxt | 包含多个Wrapper,每个Conetext对应一个servlet Project,session的管理层 |
Host | 虚拟主机,包含多个Context,主要用于proxy和多端口复用 |
Engine | 顶级容器,包含所有项目,包含多个Host |
REST设计中引入一个很重要的概念,资源。Servlet对数据的解析,本质上也是一种对资源的转换。例如,查询某一条记录,输入一组特别标志,获得特定标志对应的数据,这相当将特定标志转化为数据,这是一种资源的转化;通过URL获取一个静态页面,url地址同样是一种请求输入,而静态页面作为URL对应的静态输出,这同样是一种资源的转化。Tomcat中对于资源的转化是由servlet完成的,Tomcat很少直接参与资源的转化,Tomcat给予Servlet资源转化最主要的是提供了完善的环境,而这种环境主要就是容器Container所提供的。
Engine是所有资源的总入口,提供了整体的容器,通过Engine可以实现多个Host虚拟主机同时存在。
Host虚拟主机为Tomcat提供了多虚拟主机配置的功能,将一个Tomcat通过虚拟主机配置,可以划分成为逻辑独立的多台虚拟服务容器。通过虚拟主机,可以实现多域名映射多虚拟主机,虚拟主机独立数据存储,虚拟主机独立配置等。
Context为服务提供容器,每一个在tomcat部署的服务都由一个Context提供服务,通过Context容器,Tomcat为我们提供了很多有趣的特性,其中很重要的一个特性就是Session和Cookie。HTTP虽然是无状态协议,但是通过Session和Cookie,HTTP协议实现了真正拥有上下文的交互方式。通过上下文,我们实现了有状态的资源交互。更重要的一点是,这种有趣的交互方式由容器来实现,而服务无需关心其实现。
Wrapper为每一个Servlet提供一个对应的容器。
一个父容器可以包含一个或多个子容器,如一个Engine可以设置多个Host。
很明显,Contianer其实是一种组合模式(Composite Pattern)。
将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
《设计模式–组合模式定义》
在《设计模式》中对于组合模式实现的时候需要关注的几个点:
1. 显式父部件引用
2. 最大化Component接口
3. 声明管理子部件的操作
因此设计Container接口如下
//添加子容器
public void addChild(Container child);
//移除子容器
public void removeChild(Container child);
//查找子容器
public Container findChild(String childName);
//子容器列表
public Container[] findChildren();
//获取父容器
public Container getParent();
//设置父容器
public void setParent(Container parent);
//获取容器名称
public String getName();
//设置容器名称
public void setName(String name);
根据Container接口,设计ContainerBase类提供如下:
public abstract class ContainerBase