tomcat架构分析(valve机制)
先看一下pipeline及valve的逻辑概念图。
这些valve就是在tomcat的server.xml中配置,只要满足一定条件,继承ValveBase基类
就可以在不同的容器中配置,然后在消息流中被逐一调用。每个容器的valve的作用域不一样,在总体结构中已有说明。这里红色标记的是配置的自定义的valve,这样可以扩展成多个其他应用,例如cluster应用等。
Tomcat实现
Tomcat提供了Pipeline的标准实现:
四大容器类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对象,想象一下,这样是不是可以批量的做很多东西?
答 : 每一层有多个valve,以Engine层为例, 都是以这个顺序
valve0,valve1,...StandardEngineValve进行调用,典型的责任链模式,各个valve之间根据一定的逻辑通过
getNext().invoke(request, response);调用下一个valve
一件事,不管有多难,会不会有结果,这都不重要,即使失败了也无可厚非,关键是你有没有勇气解脱束缚的手脚,有没有胆量勇敢地面对。很多时候,我们不缺方
法,缺的是一往无前的决心和魄力。不要在事情开始的时候畏首畏尾,不要在事情进行的时候瞻前顾后,唯有如此,一切才皆有可能。
tomcat架构分析(valve机制)的更多相关文章
- tomcat架构分析(valve源码导读)
出处:http://gearever.iteye.com 源码面前,了无秘密 ----侯捷 在tomcat架构分析(valve机制)(http ...
- tomcat架构分析-索引
出处:http://gearever.iteye.com tomcat架构分析 (概览) tomcat架构分析 (容器类) tomcat架构分析 (valve机制) tomcat架构分析 (valve ...
- tomcat架构分析(connector BIO 实现)
出处:http://gearever.iteye.com 在tomcat架构分析(概览)中已经介绍过,connector组件是service容器中的一部分.它主要是接收,解析http请求,然后调用本s ...
- tomcat架构分析 (Session管理)
Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是获取一个session,然后向session中存取数据,然后再销毁session.那么如何产生se ...
- tomcat架构分析 (connector NIO 实现)
出处:http://gearever.iteye.com 上一篇简单记录了缺省配置的connector的内部构造及消息流,同时此connector也是基于BIO的实现.除了BIO外,也可以通过配置快速 ...
- tomcat架构分析(概览)
出处:http://gearever.iteye.com Tomcat是目前应用比较多的servlet容器.关于tomcat本身的特点及介绍,网上已经有很多描述了,这里不再赘述.Tomcat除了能够支 ...
- tomcat架构分析及配置详解
浏览器访问服务器的流程 请求发起的过程: 注意:浏览器访问服务器使用的是http协议,http是应用层协议,而具体传输还是使用的TCP/IP协议 Tomcat系统总架构 2.1 Tomcat请求处理过 ...
- tomcat架构分析(容器类)
Tomcat提供了engine,host,context及wrapper四种容器.在总体结构中已经阐述了他们之间的包含关系.这四种容器继承了一个容器基类,因此可以定制化.当然,tomcat也提供了标准 ...
- tomcat架构分析和源码解读
最近在看<深入分析java web技术内幕>,书中讲解了一部分tomcat的相关知识,我也去查看了一些源码,看了大神们写的代码,我才知道自己就像在做加减乘除一样,这是不行的.还有好多包和类 ...
随机推荐
- 请求(Request)的参数(Param)里包含特殊字符(#等)的正确处理方式
当调用restful接口,并且url中有参数传过去时,比如http://test.com?param=woshi#miaoyinga. 后台在使用@RequestParam("param&q ...
- 【死磕 Spring】—— IoC 之 Spring 统一资源加载策略
本文主要基于 Spring 5.0.6.RELEASE 摘要: 原创出处 http://svip.iocoder.cn/Spring/IoC-load-Resource/ 在学 Java SE 的时候 ...
- django中路由系统和视图的对应关系(值的传递)-->主要内容(位置参数、关键字参数、额外参数、include分组[urls的分发]、命名分组、反向解析、APPEND_SLASH)
路由系统也就是 urls.py文件,视图就是 views.py文件 路由系统里面要注意的事项 urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续. 若要从UR ...
- js --- 关于DOM的事件操作
一.JavaScript的组成 JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象 ...
- 20165205 2017-2018-2 《Java程序设计》实验二 Java面向对象程序设计
20165205 2016-2017-2 <Java程序设计>实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UM ...
- [Unity工具]批量修改Texture
BatchModifyTexture.cs using UnityEngine; using System.Collections; using UnityEditor; using System.I ...
- HDFS在web端无法访问文件
解决办法1: [root@djt002 hadoop]# vi /etc/selinux/config 改为 SELINUX=disabled 解决办法2: 查看你的$HADOOP_HOME/etc/ ...
- Strandbeest mechanism and Leg mechanism
I have to say besides computer science study, I'm also interested in Leg mechanism. Share two keywor ...
- 用javascript控制svg的图片颜色
SVG:(1.svg) <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC ...
- Yii框架中使用SRBAC作为权限管理模块时遇到的问题
Yii框架中使用SRBAC作为权限管理模块时遇到的问题 看到Yii中提供RBAC的插件,SRBAC,就想用用. 结果按照手册上的安装办法,整来整去,安装完了,可就是进不了权限管理界面. 最后想到, ...