第四章:容器初探
接触JAVA
EE以来,最初对“容器”一词满头雾水、无比崇拜,后来听到耳朵长茧,一直觉得这个词的定义有点太广了,很多情况下不管沾没沾点关系的都往上靠,力图通过
此术语使自己显得“专业”一些(老实说我写文档也这么做过)。但不论如何,发明这个计算机术语的人还是相当牛的,充分体现了JAVA
EE“分层”的思想。
唯一不爽的是,一直以来都处于“容器”的黑盒之外,更加上那些大厂商对自己的JAVA
EE“容器”产品的神乎其神的吹嘘宣传,一直没法想象外国那些鬼佬怎么就这么牛能做出这么厉害的东西,我们只有乖乖使用的份?还好有开源,还好有这本
《How Tomcat Works》,可以满足我的好奇心,一窥“容器”的奥秘
Tomcat的容器架构
我们一般都把tomcat、weblogic、websphere app server和JBOSS
AS称为“J2EE容器”,是一种广义的说法;而这里的“容器”,指的是tomcat中的两大组件之一的“容器”,属于狭义的说法(另一种组件当然就是
Connector了)。
tomcat的容器架构,一直都没有太大变化,基本元素都是四个接口:
-
engine:表示一整个Catalina Servlet引擎
-
host:表示一个虚拟主机。什么是虚拟主机可以百度一下“tomcat 虚拟主机配置”
-
Context:表示一个web app应用,比如你做的一个网站
-
Wrapper:表示单个Servlet
以上四个基本元素由上至下逐渐细分,成树状结构,构成了tomcat容器结构的主体,它们都位于org.apache.catalina包
值得一提的是,这四个接口并不是同时必须的,例如,你完全可以做一个只有Wrapper的“迷你版”tomcat,这在一些资源受限的环境中,比如嵌入式系统很有用(说不定将来能放到手机里面跑,O(∩_∩)O哈哈~)
类图如下:
一般来说,容器里头都还有session管理、日志等功能,不过这一章暂时还不作讨论。
PipeLine & Valve
熟悉Servlet的人一定接触过Servlet
filter,在Servlet处理请求之前,先会由filter“过滤”一下。tomcat内部同样也有类似的东西,那就是Valve——阀门。而所有
的Valve都是装在一个pipeline(管道)里头的,tomcat的开发者估计对水管工之类的活比较感兴趣。这些Valve的功能各异,你也可以自
己开发然后放到tomcat的配置文件里面。
那具体是如何工作的呢?首先
,Connector调用容器的invoke方法,把Request给容器,容器再把Request对象给自身的pipeline:
public void invoke(Request request, Response response)
throws IOException, ServletException {
pipeline.invoke(request, response);
...
}
然后
,在pipeline内部有个内部类ValveContext,它来管理所有的Valve。pipeline一般会调用ValveContext的invokeNext
public void invokeNext(Request request, Response response)
ValveContext又调用第N个Valve的invoke方法(N是一个计数器,记录调用到第几个Valve了),不过参数稍微有点不同
public void invoke(Request request, Response response,
ValveContext ValveContext
) throws IOException, ServletException
它把自己作为参数传了进去给Valve,有什么用呢?其实很简单,看看Valve的invoke是怎么实现的
public void invoke(Request request, Response response,
ValveContext valveContext) throws IOException, ServletException {
// Pass the request and response on to the next valve in our pipeline
valveContext.invokeNext(request, response);
// now perform what this valve is supposed to do
...
}
秘密就在这里!Valve又回调
了ValveContext的invokeNext,这样就相当于递归一样,把全部Valve都调用一遍。
仔细推敲会发现,每个Valve都是先调用ValveContext的invokeNext,然后才做自己的工作,所以“第一个”被
pipeline调用的Valve,实际却是最后一个完成自己工作的,有点类似“压栈”操作,第一个Valve最先被压进去,却是最后一个从堆栈中弹出来
的。如果不信,可以做个试验,眼见为实。
修改BasicValve
每个pipeline默认会有一个basicvalve,做一些基本工作,比如把Request传递给下一级子容器,或者把Request交给
Servlet(Wrapper的basicvalve就是做这个的)。从pipeline的源码来看(书中的源码,未必是tomcat的源
码),basicvalve是最后一个被调用的。
if (subscript < valves.length) { valves[subscript].invoke(request, response, this);
}
else if ((subscript == valves.length) && (basic != null)) {
basic.invoke(request, response, this);
}
以上是ValveContext.invokeNext方法的一部分,basic就是指BasicValve,很明显是最后一个被加进去的。
我们在basicvalve的invoke方法第一行增加一个简单的输出,运行之后就会发现,basicvalve的输出在其他Valve的前面,可见上面的推断是正确的!
关于Wrapper的疑问
这一章最后是两个简单的程序:第一个只有Wrapper容器,另一个则由两个Wrapper包含在一个Context容器里组成。Wrapper和
Context接口就不啰嗦了,在后续章节有专门的详细解说。但在这里,每个Wrapper对应一个Servlet,如果是个大项目,那里面的
Servlet起码有几十个,很难想像有那么多的Wrapper在同时跑,会不会导致性能低下呢?也许要看完这本书才能找到答案了
keep moving,坚持每周看一章~!
分享到:
相关推荐
How Tomcat Works中文版
How Tomcat Works【英文PDF+中文HTML+源码】 How Tomcat Works 主要是讲解Tomcat如何运行的一些核心资料。
How Tomcat Works 中文版+例程源码; 源码在src目录下
NULL 博文链接:https://asialee.iteye.com/blog/521414
NULL 博文链接:https://com0606.iteye.com/blog/1045568
How Tomcat works(PDF),不可用于商业用途,如有版权问题,请联系删除!
tomcat的基本思想,学习完可以对理解spring的基本原理有大致了解,很值得学习
how tomcat works一书中的全部代码 java类
HowTomcatWorks 中文版+源码.rar HowTomcatWorks 中文版+源码.rar
how tomcat works中文版 + 英文版,深入解析了tomcat的实现机制
How Tomcat Works》这本书的读书笔记,及主要内容感想。 作为一个世界范围广泛使用的强大框架,Tomcat必然有非常多的设计思想、设计模式,让我们学习。
How Tomcat Works Tomcat原理的书
How Tomcat Works 全书共20章!
how tomcat works 高清版 学习tomcat必备书籍 how tomcat works
HowTomcatWorks(书和源码)
HowTomcatWorks中文版HowTomcatWorks中文版 http://www.docin.com/p-58566711.html# suse安装oracle10 http://www.cnblogs.com/zhou__zhou/archive/2009/06/23/oracle_install.html
How Tomcat Works 深入剖析Tomcat (英文版)
tomcat工作原理深入详解——HowTomcatWorks中文版.pdf