出处:http://gearever.iteye.com

关于tomcat的内部逻辑单元的存储空间已经在相关容器类的blog里阐述了。在每个容器对象里面都有一个pipeline及valve模块。它们是容器类必须具有的模块。在容器对象生成时自动产生。Pipeline就像是每个容器的逻辑总线。在pipeline上按照配置的顺序,加载各个valve。通过pipeline完成各个valve之间的调用,各个valve实现具体的应用逻辑。 
先看一下pipeline及valve的逻辑概念图。 

这些valve就是在tomcat的server.xml中配置,只要满足一定条件,继承ValveBase基类

引用
org.apache.catalina.valves.ValveBase

就可以在不同的容器中配置,然后在消息流中被逐一调用。每个容器的valve的作用域不一样,在总体结构中已有说明。这里红色标记的是配置的自定义的valve,这样可以扩展成多个其他应用,例如cluster应用等。 
Tomcat实现

Tomcat提供了Pipeline的标准实现:

引用
org.apache.catalina.core.StandardPipeline

四大容器类StandardEngine,StandardHost,StandardContext及StandardWrapper都有各自缺省的标准valve实现。它们分别是

  • Engine:org.apache.catalina.core.StandardEngineValve
  • Host: org.apache.catalina.core.StandardHostValve
  • Context:org.apache.catalina.core.StandardContextValve
  • Wrapper:org.apache.catalina.core.StandardWrapperValve

容器类生成对象时,都会生成一个pipeline对象,同时,生成一个缺省的valve实现,并将这个标准的valve对象绑定在其pipeline对象上。以StandardHost类为例:

Java代码
public class StandardHost extends ContainerBase implements Host {   protected Pipeline pipeline = new StandardPipeline(this);   public StandardHost() {   super();   pipeline.setBasic(new StandardHostValve());   }   }

Valve实现了具体业务逻辑单元。可以定制化valve(实现特定接口),然后配置在server.xml里。每层容器都可以配置相应的valve,当只在其作用域内有效。例如engine容器里的valve只对其包含的所有host里的应用有效。定制化的valve是可选的,但是每个容器有一个缺省的valve,例如engine的StandardEngineValve,是在StandardEngine里自带的,它主要实现了对其子host对象的StandardHostValve的调用,以此类推。 
配置的例子有:

Xml代码
<Engine name="Catalina" defaultHost="localhost">  <Valve className="MyValve0"/>  <Valve className="MyValve1"/>  <Valve className="MyValve2"/>  ……  <Host name="localhost"  appBase="webapps">  </Host>
</Engine>

当在server.xml文件中配置了一个定制化valve时,会调用pipeline对象的addValve方法,将valve以链表方式组织起来,看一下代码;

Java代码
public class StandardPipeline implements Pipeline, Contained, Lifecycle{   protected Valve first = null;   public void addValve(Valve valve) {   // Validate that we can add this Valve   if (valve instanceof Contained)   ((Contained) valve).setContainer(this.container);   // Start the new component if necessary   if (started) {   if (valve instanceof Lifecycle) {   try {   ((Lifecycle) valve).start();   } catch (LifecycleException e) {   log.error("StandardPipeline.addValve: start: ", e);   }   }   // Register the newly added valve
       registerValve(valve);   }   // 将配置的valve添加到链表中,并且每个容器的标准valve在链表的尾端  if (first == null) {   first = valve;   valve.setNext(basic);   } else {   Valve current = first;   while (current != null) {   if (current.getNext() == basic) {   current.setNext(valve);   valve.setNext(basic);   break;   }   current = current.getNext();   }   }  }
}

从上面可以清楚的看出,valve按照容器作用域的配置顺序来组织valve,每个valve都设置了指向下一个valve的next引用。同时,每个容器缺省的标准valve都存在于valve链表尾端,这就意味着,在每个pipeline中,缺省的标准valve都是按顺序,最后被调用。 
消息流 
先看一下四大容器的标准valve的调用逻辑图。从中可以梳理出标准valve的逻辑。注意此图只是在缺省配置下的状态,也就是说每个pipeline只包含一个标准valve的情况。 
 
图中显示的是各个容器默认的valve之间的实际调用情况。从StandardEngineValve开始,一直到StandardWrapperValve,完成整个消息处理过程。注意每一个上层的valve都是在调用下一层的valve返回后再返回的,这样每个上层valve不仅具有request对象,同时还能拿到response对象,想象一下,这样是不是可以批量的做很多东西?

转载于:https://www.cnblogs.com/nizuimeiabc1/p/8934126.html

tomcat架构分析(valve机制)相关推荐

  1. tomcat架构分析(valve机制)【转】

    原文地址:https://www.iteye.com/blog/gearever-1536022 关于tomcat的内部逻辑单元的存储空间已经在相关容器类的blog里阐述了.在每个容器对象里面都有一个 ...

  2. tomcat架构分析(valve源码导读)【转】

    原文地址:https://www.iteye.com/blog/gearever-1540028 源码面前,了无秘密                               ----侯捷  在to ...

  3. tomcat架构分析(connector BIO 实现)【转】

    原文地址:https://www.iteye.com/blog/gearever-1841586 在tomcat架构分析(概览)中已经介绍过,connector组件是service容器中的一部分.它主 ...

  4. tomcat架构分析 (Session管理)【转】

    原文地址:https://www.iteye.com/blog/gearever-1546423 Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是 ...

  5. tomcat架构分析(概览)【转】

    原文地址: https://www.iteye.com/blog/gearever-1532822 Tomcat是目前应用比较多的servlet容器.关于tomcat本身的特点及介绍,网上已经有很多描 ...

  6. tomcat架构分析(容器类)【转】

    原文地址:https://www.iteye.com/blog/gearever-1533678 Tomcat提供了engine,host,context及wrapper四种容器.在总体结构中已经阐述 ...

  7. tomcat架构分析(容器类)

    Tomcat提供了engine,host,context及wrapper四种容器.在总体结构中已经阐述了他们之间的包含关系.这四种容器继承了一个容器基类,因此可以定制化.当然,tomcat也提供了标准 ...

  8. tomcat架构分析 (connector NIO 实现)【转】

    原文地址:https://www.iteye.com/blog/gearever-1844203 ller线程中维护的这个Selector标为主Selector.  Poller是NIO实现的主要线程 ...

  9. 应用服务器——tomcat架构分析

    先mark,后续补充 https://blog.csdn.net/qq_38245537/article/details/79009448

最新文章

  1. android 布局翻页,安卓APP_ 布局(8) —— 基于 RecyclerView 的 ViewPager2翻页
  2. Swift2.0语言教程之函数的返回值与函数类型
  3. c 语言切换源码,C转换为pas - 源码下载|其它|编译器/词法分析|源代码 - 源码中国...
  4. sklearn自学指南(part39)--Birch
  5. GitHub建立个人网站(二)
  6. c-free5.0运行程序错误_web前端之异常/错误监控
  7. java poi导出Excel表格超大数据量解决方案
  8. css多重颜色渐变,CSS多重渐变颜色停止
  9. 基于SSM车牌识别停车场管理系统
  10. 数据分析软件及spss简单操作
  11. Windows 下 FTP的搭建
  12. VS2008打开时出现devenv.exe 应用程序错误 该内存不能为written
  13. 七大江河水系--长江(一)
  14. 关于扫码签到统计信息,一键导出excel表
  15. perf常用命令(perf top perf record perf stat)
  16. 7-21 九宫格输入法 (15 分)
  17. Opencv实战 文字区域的提取
  18. [笔记] APIO 2018 Day1
  19. [2017纪中10-26]摘Galo 树型背包
  20. 有哪些好用的设备巡检类的软件?

热门文章

  1. CTFshow 命令执行 web68
  2. Rotate List
  3. 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果。
  4. opencv矩阵运算(1)
  5. oracle12c多个pdb,Oracle 12c 多租户专题|12cR2中PDB内存资源管理
  6. 【HDU6662】Acesrc and Travel【树形DP】
  7. pymysql.err.IntegrityError: (1062, Duplicate entry 'roxml-ROXML' for key 'PRIMARY')
  8. Python自动化开发 - RESTful API
  9. 五大经常使用算法 之 动态规划法
  10. 如何将git上的代码迁移到Coding上