博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tomcat架构分析(valve机制)
阅读量:4438 次
发布时间:2019-06-07

本文共 3155 字,大约阅读时间需要 10 分钟。

出处: 

关于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代码
……

 

当在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

你可能感兴趣的文章
接口、抽象类、方法复写、类Equals方法重写
查看>>
快学Scala习题解答—第十章 特质
查看>>
Ffmpeg 定位文件(seek file)
查看>>
数据结构与算法随学随记
查看>>
微软Azure已开始支持hadoop--大数据云计算
查看>>
统计_statistics_不同的人_大样本_分析_统计方法_useful ?
查看>>
wampserver 绑定域名 外部可以正常访问
查看>>
将博客搬至CSDN
查看>>
sqoop/1.4.6/下载
查看>>
https协议及与http协议的比较
查看>>
mongodb数据备份与恢复
查看>>
ubuntu安装(owncloud-docker安装)
查看>>
(十一)tina | openwrt关闭调试串口(DEBUG UART)
查看>>
Android中获取TextView行数
查看>>
AngularJS 学习笔记值post传值
查看>>
maven+springMVC+mybatis+junit详细搭建过程
查看>>
iframe详细用法
查看>>
angularjs 使用angular-sortable-view实现拖拽效果(包括拖动完成后的方法使用)
查看>>
2015生命之旅---南京、南通、上海之行
查看>>
高精度练习之乘法(codevs_3117)
查看>>