内容简介:于每一个Java工程师而言,tomcat这只小橘猫算是我们的老朋友了,同时tomcat作为一款服务器中间件具备了很强的扩展性,内部对于Request和Response的逻辑处理都是何种方式来实现的呢?本文将主要介绍tomcat的Pipeline-Valve设计来一窥究竟。首先我们看看Valve接口可以从Valve看到很多链表的影子,我们可以根据Valve来构造一条Valve链。接下来看看Pipeline接口
于每一个 Java 工程师而言,tomcat这只小橘猫算是我们的老朋友了,同时tomcat作为一款服务器中间件具备了很强的扩展性,内部对于Request和Response的逻辑处理都是何种方式来实现的呢?本文将主要介绍tomcat的Pipeline-Valve设计来一窥究竟。
接口介绍
首先我们看看Valve接口
可以从Valve看到很多链表的影子,我们可以根据Valve来构造一条Valve链。接下来看看Pipeline接口
Pipeline接口的主要方法
可以看到Pipeline的主要方法提供了对Valve的增删查改操作,其中有两个关键的方法setBasic(Valve)与addValve(Valve)我们跟进源码看一看。其中StandardPipeline是Pipeline接口的实现类,下面我截取了setBasic最核心的逻辑,可以看出basic实际上就是Pipeline维护的Valve链里最末尾的一个Valve
Valve current = first; while (current != null) { if (current.getNext() == oldBasic) { current.setNext(valve); break; } current = current.getNext(); } this.basic = valve; 复制代码
同样的我们来看一看addValve的源码,以下是最核心的部分
Valve current = first; while (current != null) { if (current.getNext() == basic) { current.setNext(valve); valve.setNext(basic); break; } 复制代码
通过addValve添加的Valve被加在了basic的前一个,也就是说basic永远指向Valve链里的最后一个Valve,不会被轻易替代,那么这种设计有什么意义呢?待会给出答案~
Valve到底是什么?
上图都是Valve接口的实现类,包含了负载均衡、单点登录等tomcat容器本身的逻辑。通过查看Valve接口invoke方法的实现可以知道,每一个Valve的invoke方法主要做两件事情
- 本身的逻辑
- 通过getNext().invoke(request, response)调用下一个Valve的逻辑
这是很经典的责任链设计模式。简单的说一个valve就是一个逻辑体。
跟踪basic
可以看到setBasic的使用方主要是tomcat内置的四大容器,Context、Engine、Host以及Wrapper,先简单对四大容器做个介绍
- Wrapper:对Servlet定义的组件概念,一个Wrapper代表一个Servlet
- Context:表示我们的应用程序,比如一个运行中Java Web程序,一个程序里面自然有多个Servlet,所以Conxtet和Wrapper的关系是1对n
- Host:表示虚拟主机的概念,因为一台服务器不仅能够对product.yangkw.com提供服务,同时也可以对test.yangkw.com提供服务,同时每个虚拟主机都可以运行多个Java Web程序,所以Host和Context的关系也是1对n
- Engine:Tomcat连接器(Connector) 将接收到的连接提交给Engine处理,作为整个Servlet引擎的组件概念,用来管理多个虚拟站点,Engine和Host也是一对n的关系
下面是关于四大容器一个简单的类图关系
那么四大容器是如何被关联在一起的呢?StandardEngineValve是Engine容器的basic valve,笔者简化了代码实现,保留最主要的逻辑
@Override public final void invoke(Request request, Response response) throws IOException, ServletException { // Select the Host to be used for this Request Host host = request.getHost(); ... // Ask this Host to process this request host.getPipeline().getFirst().invoke(request, response); } 复制代码
可以看到Engine容器的basic valve负责触发host容器pipeline 答案出来了: 每个容器的basic valve会去触发子容器的pipeline ,所以basic作为一个valve不仅要执行自身相应的逻辑,同时也扮演了一个外交官的角色负责去和其子容器逻辑的对接。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 架构设计(7)——如何设计一个架构
- 架构设计(8)—高可用架构设计
- 如何设计实时数据平台(设计篇)
- Token经济设计专家叶开:Token设计画布与10大设计模式
- 数据可视化设计(1)情感化设计指导可视化设计理念
- 架构设计笔记(八):详细方案设计
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
UML基础、案例与应用
施穆勒 / 李虎、赵龙刚 / 人民邮电出版社 / 2004-7-1 / 42.00元
本书教读者循序渐进地、系统地学习UML基础知识和应用技术。和前一版相比,本书内容根据UML 2.0进行了补充和更新,随书光盘包含了建模工具Poseidon的试用版。 全书分为三部分24章。第一部分“基础知识”包括第1章到第15章,主要是介绍UML语言的基础知识以及面向对象的概念和思想,还简单介绍了UML在开发过程的应用方法。第二部分“学习案例”包括第16章到第22章,结合实例详细分析了UML的应用......一起来看看 《UML基础、案例与应用》 这本书的介绍吧!