责任链模式

来自ling
跳转至: 导航搜索

Container 是容器的父接口,所有子容器都必须实现这个接口。Tomcat 中有四个子容器组件,分别是:Engine、Host、Context、Wrapper,这四个组件之间不是平行关系,而是父子关系。Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper。下面是四个

Container 的核心功能。

  • Engine:用于管理多个站点,一个 Service 最多只能有一个 Engine。
  • Host:代表一个站点,也可以叫虚拟主机,通过在 server.xml 配置文件就可以添加 Host,一个 Host 下可以运行多个 Context,但是在实践中,单 JVM 的处理能力有限,一般一个 Tomcat 实例只会配置一个 Host,也只会配置一个 Context。
  • Context:代表一个应用程序,对应你在日常开发的一个 Web 应用。Context 最重要的功能就是管理它里面的 Servlet 实例,并为 Request 匹配正确的 Servlet。Servlet 实例在 Context 中是以 Wrapper 出现的。
  • Wrapper:一个 Wrapper 负责管理一个 Servlet,包括 Servlet 的装载、初始化、执行以及资源回收。Wrapper 是最底层的容器,它没有子容器了。

下面这张图大致展示了从 Connector 开始接收请求,经过 Engine、Host、Context、Wrapper,最终到 Servlet 的流程,这里需要关注的是拿到 Request 请求对象之后的处理: Tomcat 责任链.png

Container 中真正处理请求的是 Valve,一组 Valve 组成一个 Pipeline,这是典型的责任链模式。责任链模式是指在一个请求处理的过程中会有很多处理器依次对请求进行处理,每个处理器只负责处理自己相应的部分,当对应的部分被处理完成之后,会将请求交给下一个处理器继续处理,直至请求完全处理完成。

以现实生活中汽车组装为例,整个责任链就像是汽车的生产线,责任链上的每个处理器则对应每个组装车间,每个组装车间只组装汽车的一部分,如下图所示:

Tomcat 责任链2.png

在每个 Container 的 Pipeline 中,我们可以增加任意多个 Valve,处理请求的 Tomcat 线程会依次执行这些 Valve,并最终完成请求的处理。在上图中我们可以看到,每个 Pipeline 都有一个特定的 Valve(即图中的 StandEngineValve、StandHostValve、StandContextValve、StandWrapperValve),而且这些 Valve 是在 Pipeline 中最后一个执行,这种 Valve 叫作BaseValve。我们可以在 Tomcat 的 server.xml 文件中自定义 Pipeline 中的 Valve,但上述四个 BaseValve 是不可删除的。这些 BaseValve 会负责调用子容器的 Pipeline,将请求传给子容器,以保证处理逻辑能继续向下执行。Valve 接口与四个标准 Valve 实现的继承关系如下图所示: