tomcat架构分析(valve机制)
出处: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类为例:
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的调用,以此类推。
配置的例子有:
<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以链表方式组织起来,看一下代码;
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机制)相关推荐
- tomcat架构分析(valve机制)【转】
原文地址:https://www.iteye.com/blog/gearever-1536022 关于tomcat的内部逻辑单元的存储空间已经在相关容器类的blog里阐述了.在每个容器对象里面都有一个 ...
- tomcat架构分析(valve源码导读)【转】
原文地址:https://www.iteye.com/blog/gearever-1540028 源码面前,了无秘密 ----侯捷 在to ...
- tomcat架构分析(connector BIO 实现)【转】
原文地址:https://www.iteye.com/blog/gearever-1841586 在tomcat架构分析(概览)中已经介绍过,connector组件是service容器中的一部分.它主 ...
- tomcat架构分析 (Session管理)【转】
原文地址:https://www.iteye.com/blog/gearever-1546423 Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是 ...
- tomcat架构分析(概览)【转】
原文地址: https://www.iteye.com/blog/gearever-1532822 Tomcat是目前应用比较多的servlet容器.关于tomcat本身的特点及介绍,网上已经有很多描 ...
- tomcat架构分析(容器类)【转】
原文地址:https://www.iteye.com/blog/gearever-1533678 Tomcat提供了engine,host,context及wrapper四种容器.在总体结构中已经阐述 ...
- tomcat架构分析(容器类)
Tomcat提供了engine,host,context及wrapper四种容器.在总体结构中已经阐述了他们之间的包含关系.这四种容器继承了一个容器基类,因此可以定制化.当然,tomcat也提供了标准 ...
- tomcat架构分析 (connector NIO 实现)【转】
原文地址:https://www.iteye.com/blog/gearever-1844203 ller线程中维护的这个Selector标为主Selector. Poller是NIO实现的主要线程 ...
- 应用服务器——tomcat架构分析
先mark,后续补充 https://blog.csdn.net/qq_38245537/article/details/79009448
最新文章
- android 布局翻页,安卓APP_ 布局(8) —— 基于 RecyclerView 的 ViewPager2翻页
- Swift2.0语言教程之函数的返回值与函数类型
- c 语言切换源码,C转换为pas - 源码下载|其它|编译器/词法分析|源代码 - 源码中国...
- sklearn自学指南(part39)--Birch
- GitHub建立个人网站(二)
- c-free5.0运行程序错误_web前端之异常/错误监控
- java poi导出Excel表格超大数据量解决方案
- css多重颜色渐变,CSS多重渐变颜色停止
- 基于SSM车牌识别停车场管理系统
- 数据分析软件及spss简单操作
- Windows 下 FTP的搭建
- VS2008打开时出现devenv.exe 应用程序错误 该内存不能为written
- 七大江河水系--长江(一)
- 关于扫码签到统计信息,一键导出excel表
- perf常用命令(perf top perf record perf stat)
- 7-21 九宫格输入法 (15 分)
- Opencv实战 文字区域的提取
- [笔记] APIO 2018 Day1
- [2017纪中10-26]摘Galo 树型背包
- 有哪些好用的设备巡检类的软件?
热门文章
- CTFshow 命令执行 web68
- Rotate List
- 十三种基于直方图的图像全局二值化算法原理、实现、代码及效果。
- opencv矩阵运算(1)
- oracle12c多个pdb,Oracle 12c 多租户专题|12cR2中PDB内存资源管理
- 【HDU6662】Acesrc and Travel【树形DP】
- pymysql.err.IntegrityError: (1062, Duplicate entry 'roxml-ROXML' for key 'PRIMARY')
- Python自动化开发 - RESTful API
- 五大经常使用算法 之 动态规划法
- 如何将git上的代码迁移到Coding上