核心部分

  1. 外观模式: RequestFacade应用门面模式(facade)来封装HttpServletRequest。
  2. 观察者模式: 事件监听机制,控制组件生命周期的 Lifecycle 、Servlet 实例的创建、Session 的管理、Container 管理等应用了观察者模式。相关的类有LifecycleListener, ContainerListener, SessionListener。。。
  3. 责任链模式:tomcat的容器设置就是责任链模式,从Engine到Host再到Context一直到Wrapper都是通过一个链传递请求。
  4. 模板方法模式:Tomcat中就将每个生命周期阶段公共的部分固化,然后通过initInternal,startInternal,stopInternal,destoryInternal这几个钩子方法开放给子类去实现具体的逻辑。
  5. 命令模式:Tomcat 中命令模式在 Connector 和 Container 组件之间有体现,Connector 作为抽象请求者,HttpConnector 作为具体请求者。HttpProcessor 作为命令。Container 作为命令的抽象接受者,ContainerBase 作为具体的接受者。
  6. 工厂模式:在Tomcat启动的过程中,调用Connector组件的startInternal()方法:

1.外观模式

定义:外观模式封装了子系统的具体实现,提供统一的外观类给外部系统,这样当子系统内部实现发生变化的时候,不会影响到外部系统。

外观模式在Tomcat的应用:在Tomcat中对于Request,Response,StandardSession,ApplicationContext,StandardWrapper都采用了外观模式,它的类图如下:

  通过上图,我们可以看到RequestFacade包装了Request,它们都实现了HttpServletRequest,当传递Request对象给应用的时候,其实是返回了RequestFacade对象,而RequestFacade内部可以根据是否自定义了安全管理器来进行相应的操作。对于Response,StandardSession等处理是类似的,这里就不赘述了。

2.观察者模式

定义:发布-订阅模式,客户端应用中的事件监听器,以及通知等其实都属于观察者模式。观察者模式主要是在当系统中发生某个状态变更或者事件的时候,有另外一些组件或者对象对此次变化有兴趣,这个时候那些对变化感兴趣的对象就可以做为观察者对象来监听变化,而被观察对象要负责发生变化的时候触发通知操作。

观察者模式在Tomcat的应用:Tomcat中需要对很多组件进行生命周期管理,为此Tomcat抽象了统一的生命周期管理骨架,通过这个骨架将所有需要进行生命周期管理的类都纳入进来管理,而这里的骨架的类图如下:

  

  通过上图我们可以看出Tomcat抽象了一个LifecycleSupport的类,而所有需要生命周期管理的组件通过LifecycleSupport类通知对某个生命周期事件感兴趣的观察者,而所有的观察者都需要实现LifecycleListener。另外我们需要关注一下EventObject对象,它里面定义了一个事件源对象,所谓事件源就是事件发生的地方,而在Tomcat的设计中,事件源就是实现了LifeCycle接口的各个需要管理生命周期的组件,这里LifecycleSupport和LifeCycleBase之间是双向的关联,LifeCycleSupport关联LifeCycle对象就是为了实现事件源的传递,这样在LifeCycleSupport触发事件的时候,可以通过事件源构建EventObject.这样以来LifecycleListener就可以通过事件对象获取到事件源,从而做一些与事件源相关的操作。

3.责任链模式

定义:当我们系统在处理某个请求的时候,请求需要经过很多个节点进行处理,每个节点只关注自己的应该做的工作,做完自己的工作以后,将工作转给下一个节点进行处理,直到所有节点都处理完毕。责任链模式在日常生活中例子挺多,比如快递,当你发一个从深圳到北京的快递的时候,你的包裹会从一个分拨中心传递到下一个分拨中心,直到目的地,这里面每个分拨中心都是链路上的一个节点,它做完自己的工作,然后将工作传递到下一个节点,还比如路由器中传递某个数据包其实也是同样的思路。

责任链模式在Tomcat的应用:Tomcat中请求的处理流程其实就是采用了责任链模式,Tomcat中责任链模式的实现的类图如下图所示:

  从上图中,我们可以看到每一个容器都会有一个Pipeline,而一个Pipeline又会具有多个Valve阀门,其中StandardEngine对应的阀门是StandardEngineValve,StandardHost对应的阀门是StandardHostValve,StandardContext对应的阀门是StandardContextValve,StandardWrapper对应的阀门是StandardWrapperValve。这里每一Pipeline就好比一个管道,而每一Valve就相当于一个阀门,一个管道可以有多个阀门,而对于阀门来说有两种,一种阀门在处理完自己的事情以后,只需要将工作委托给下一个和自己在同一管道的阀门即可,第二种阀门是负责衔接各个管道的,它负责将请求传递给下个管道的第一个阀门处理,而这种阀门叫Basic阀门,它是每个管道中最后一个阀门,上面的Standard*Valve都属于第二种阀门。我们可以形象的通过下图来描述上面的过程:

  通过上图,我们可以很清楚的了解到Tomcat的请求处理流程。当用户请求服务器的时候,Connector会接受请求,从Socket连接中根据http协议解析出对应的数据,构造Request和Response对象,然后传递给后面的容器处理,顶层容器是StandardEngine,StandardEngine处理请求其实是通过容器的Pipeline进行的,而Pipeline其实最终是通过管道上的各个阀门进行的,当请求到达StandardEngineValve的时候,此阀门会将请求转发给对应StandardHost的Pipeline的第一个阀门处理,然后以此最终到达StandardHostValve阀门,它又会将请求转发给StandardContext的Pipeline的第一个阀门,这样以此类推,最后到达StandardWrapperValve,此阀门会根据Request来构建对应的Servelt,并将请求转发给对应的HttpServlet处理。从这里我们可以看出其实Tomcat核心处理流程就是通过责任链一步步的组装起来的。

4.模板方法模式

定义:模板方法模式抽象出某个业务操作公共的流程,将流程分为几个步骤,其中有一些步骤是固定不变的,有一些步骤是变化的,固定不变的步骤通过一个基类来实现,而变化的部分通过钩子方法让子类去实现,这样就实现了对系统中流程的统一化规范化管理。\

模板方法模式在Tomcat的应用:Tomcat中关于生命周期管理的地方很好应用了模板方法模式,在一个组件的生命周期中都会涉及到init(初始化),start(启动),stop(停止),destory(销毁),而对于每一个生命周期阶段其实都有固定一些事情要做,比如判断前置状态,设置后置状态,以及通知状态变更事件的监听者等,而这些工作其实是可以固化的,所以Tomcat中就将每个生命周期阶段公共的部分固化,然后通过initInternal,startInternal,stopInternal,destoryInternal这几个钩子方法开放给子类去实现具体的逻辑。Tomcat中关于模板方法模式的实现如下图所示:

  

5.命令模式

定义:命令模式将请求封装为一个命令,将命令发送者和命令接受者解耦,并且所有命令对客户端来说都有统一的调用接口,使用命令模式还可以支持命令的撤销操作,在很多GUI程序中大量使用了此模式。

  接下来我们来说一个场景大家感受下,我们有时候可能会遇到接口方法参数过多的问题,这样的接口不仅看起来丑陋而且不方便阅读,对客户端不友好。遇到这种情况我们可能选择将各种参数打包为一个参数对象,接口只需要一个参数对象即可,但是在具体的接口实现中,我们又要做条件判断根据参数值的不同做出不同的响应操作,这个时候其实就可以考虑将不同的逻辑实现和各种参数通过命令打包,然后提供一个命令工厂,客户端通过工厂生产出命令,然后直接调用即可。
  其实在日常生活中,命令模式也很常见,比如公司老大给你分配了个任务,让你去做,他可能不关心你具体怎么做的,你做完了以后告诉他结果即可。

命令模式在Tomcat的应用:命令模式在Tomcat中主要是应用在对请求的处理过程中,Tomcat的实现中,根据它支持两种协议AJP和Http,而在具体的IO实现中,又分为Java同步阻赛IO,Java同步非祖塞IO,以及采用APRApache Portable Runtime 支持库,因此Tomcat统一了org.apache.coyote.Processor接口,根据协议和IO实现的不同通过不同的Process子类去实现,Connector作为客户端每次只需要根据具体的协议和IO实现创建对应的Process执行即可。下面我们来看一下命令模式在Tomcat中实现的相关类图:

  

  通过上图我们可以清楚的看到,Tomcat首先根据协议的不同将Processor分为了Ajp和Http两组,然后又根据具体的IO实现方式的不同,将每一组都会实现同步祖塞IO,同步非祖塞IO,以及APR的Processor。 接下来我们再来看一个类图,我们就可以更加清楚的看到Tomcat中是如何利用命令模式来根据不同的协议以及IO实现方式来处理请求的。我们来看一下Tomcat中关于ProtocolHandler的类图。

  通过上图我们可以看到针对每一种协议和IO实现方式的组合,都会有相应的协议处理类,而每个协议处理类都会有一个Handler,而每一个Handler在运行的时候就会创建出对应的Processor,比如AjpProtocol.AjpConnectionHandler创建AjpProcessor处理器,其它的类似。

抄录网址

  1. Tomcat 设计模式总结(Tomcat源代码阅读系列之八)
  2. Tomcat设计模式
  3. java 23种设计模式及其在spring,tomcat,jdk中的应用
  4. Tomcat中设计模式-模板模式
  5. Tomcat中涉及哪些设计模式
  6. Tomcat用到的设计模式
  7. Tomcat 系统架构与设计模式,第 2 部分

Tomcat系列(10)——Tomcat主要设计模式5种(外观,责任链,观察者,模板方法,命令模式)的更多相关文章

  1. Java设计模式(14)责任链模式(Chain of Responsibility模式)

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...

  2. java设计模式解析(11) Chain责任链模式

    设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析(4) ...

  3. php设计模式课程---5、责任链模式是什么

    php设计模式课程---5.责任链模式是什么 一.总结 一句话总结: 自己权限不够,就交给上级处理 1.选择结构怎么做到面向对象开闭原则? 也就是说if,都可以用接口的实现来实现,这样就避免了更新的时 ...

  4. Tomcat系列(11)——Tomcat 部署web应用的4种方法

    核心内容 1.在Tomcat中有四种部署Web应用的方式,分别是: (1)利用Tomcat自动部署(项目直接拷贝OR WAR包拷贝 到webapps下) (2)利用控制台进行部署(tomcat的man ...

  5. Tomcat系列(4)——Tomcat 组件及架构详细部分

    核心部分   1. 定义 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta ...

  6. Tomcat系列(9)——Tomcat 6方面调优(内存,线程,IO,压缩,缓存,集群)

    核心部分 内存 线程 IO 压缩 缓存 集群 一.JVM内存优化 Tomcat内存优化,包括内存大小,垃圾回收策略. Windows 下的catalina.bat,Linux 下的catalina.s ...

  7. Tomcat系列(5)——Tomcat配置详细部分

    Tomcat的架构图 Tomcat的组织结构 Tomcat是一个基于组件的服务器,它的构成组件都是可配置的,其中最外层的是Catalina servlet容器,其他组件按照一定的格式要求配置在这个顶层 ...

  8. Tomcat系列(3)——Tomcat 组件及架构核心部分 4类主要组件(顶层,连接器,容器,嵌套)

    1.架构图 2. 定义 Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta ...

  9. Tomcat系列(7)——Tomcat类加载机制

    1. 核心部分 1. 类加载器: 通过一个类的全限定名来获取描述此类的二进制字节流. 对于任意一个类,都需要由加载他的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一 ...

随机推荐

  1. Android View的重绘过程之Measure

    博客首页:http://www.cnblogs.com/kezhuang/p/ View绘制的三部曲,  测量,布局,绘画今天我们分析测量过程 view的测量是从ViewRootImpl发起的,Vie ...

  2. VR一体机如何退出FFBM

            Fast Factory Boot Mode(FFBM)是一种半开机的模式,它的主要目的是方便工厂测试,提高生产效率.正常情况下终端用户是不会碰到的.但售后的同学最近连续收到几台客户退 ...

  3. ext整合highcharts实现饼图

    extjs自身有图表的功能,但是与highcharts和echarts相比,ext不如它们功能强大.样式美观. 公司项目的前端框架使用的是ext,所以就有了ext整合第三方图表插件的需求. 笔者会一点 ...

  4. C#标识符与关键字

    标识符是指在程序中用来表示实物的单词,是分配给类型(类.结构.枚举.接口或委托).成员.变量或命名空间的名称.有效标识符必须遵循以下原则: 标识符不能以数字开头也不能包含空格: 标识符可以包含大小写字 ...

  5. WebApi接收post方式传入的json数据

    [RoutePrefix("Api")] public class UploadController:BaseApiController { [HttpPost] [Route(& ...

  6. w3wp.exe进程占用内存过高解决方法

    解决CPU占用过多: 1.在IIS中对每个网站进行单独的应用程序池配置.即互相之间不影响. 2.设置应用程序池的CPU监视,不超过25%(服务器为4CPU),每分钟刷新,超过限制时关闭. 根据w3wp ...

  7. Swift中 删除Array的元素对象

    Swift中Array的删除对象 在Swift中数组Array没有removeObject的方法 1.找到下标 let model_index = selectedArray.index(where: ...

  8. Thermostat:双层存储结构的透明巨页内存管理机制

    这是一篇由密歇根大学的Neha Agarwal 和 Thomas F. Wenisch,发表在计算机系统顶会ASLOS的论文,Thermostat: Application-transparent P ...

  9. c++11の泛型算法

    一.泛型算法泛型算法这个概念是针对容器操作的,我们知道,c++11的顺序容器有vector,list,deque等,对于这些容器,c++11并没给出相应的增删改查方法,而是定义了一组泛型算法 一般的泛 ...

  10. Command "python setup.py egg_info" failed with error code 1 in C:\Users\w5659\AppData\Local\Temp\pip-install-t7uomu4r\xa dmin\

    Error msg: C:\Users\w5659>pip install xadmin Collecting xadmin Using cached https://files.pythonh ...