How tomcat works 读书笔记十三 Host和Engine
Host
Host是Context的父容器。如果想在一个tomcat上部署多个context就需要使用Host了。上下文容器的父容器是主机,但是可能有一些其它实现,没有必要的时候也可以忽略。不过在实践中,即使是一个Context,我们也使用了Host,为什么?后面我们再说。
Host是个接口,里面有个map方法比较重要
/**
* Return the Context that would be used to process the specified
* host-relative request URI, if any; otherwise return <code>null</code>.
*
* @param uri Request URI to be mapped
*/
public Context map(String uri);
根据url来返回一个Context。
Host的标准实现是StandardHost
构造函数,不解释
public StandardHost() {
super();
pipeline.setBasic(new StandardHostValve());
}
StandardHost并没有invoke方法,它需要调用ContainerBase的invoke方法。
//ContainerBase.java
public void invoke(Request request, Response response)throws IOException, ServletException {
pipeline.invoke(request, response);
}
另外StandardHostValve这个基础阀会调用StandardHost的map方法获得一个context容器。
public void invoke(Request request, Response response,
ValveContext valveContext)
throws IOException, ServletException {
....
StandardHost host = (StandardHost) getContainer();
//这里调用的是ContainerBase的map方法 最终会调用StandardHost的map方法(两个map方法没有关系 没有//复写 参数都不一样)
Context context = (Context) host.map(request, true);
....
}
StandHostMapper
在ContainerBase的start中有如下的代码
addDefaultMapper(this.mapperClass);
看ConntainerBase
ContainerBase.java
protected void addDefaultMapper(String mapperClass) {
......
// Instantiate and add a default Mapper
Class<?> clazz = Class.forName(mapperClass);
Mapper mapper = (Mapper) clazz.newInstance();
mapper.setProtocol("http");
addMapper(mapper);
......
}
这里我又一个小问题,为什么ContainerBase的start中的
addDefaultMapper(this.mapperClass);
调用的是子类中的addDefaultMapper呢?
StandardHost.java
protected void addDefaultMapper(String mapperClass) {
// 参数默认为 "org.apache.catalina.core.StandardHostMapper";
super.addDefaultMapper(this.mapperClass);
}
StandardHost的start方法在结尾的时候会调用父类的start方法。
注意:Tomcat4 中的 standardContext 使用了不同的方法来创建一个默认映射器。它的 start 方法中并没有调用 super.start()。相反 Standardcontext 的start 方法调用 addDefaultMapper 来传递 mapperClass 变量。
StandardHostMapper的map方法就是调用StandardHost的map方法。
public Container map(Request request, boolean update) {
...
String uri = ((HttpRequest) request).getDecodedRequestURI();
Context context = host.map(uri);
...
return (context);
}
在得到上下对象的时候需要一个往返过程,map 方法介绍两个参数,该方法是在 ContainerBase 中的。然后 ContainerBase 类又在它的子对象中查找合适的映射器并调用它的 map 方法。
StandardHostValve
这是Host的基础阀,什么时候注入的?大家自己想。
StandardHostValve这个基础阀会调用StandardHost的map方法获得一个context容器。
public void invoke(Request request, Response response,
ValveContext valveContext)
throws IOException, ServletException {
....
StandardHost host = (StandardHost) getContainer();
//这里调用的是ContainerBase的map方法 最终会调用StandardHost的map方法(两个map方法没有关系 没有//复写 参数都不一样)
Context context = (Context) host.map(request, true);
....
HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
String sessionId = hreq.getRequestedSessionId();
if (sessionId != null) {
Manager manager = context.getManager();
if (manager != null) {
Session session = manager.findSession(sessionId);
if ((session != null) && session.isValid())
session.access(); //修改session的最后访问时间
}
}
context.invoke(request, response); //最后调用context的invoke
}
为什么必须要有一个Host容器
想想我们之前的SimpleConextConfig,它的作用是将context的configured设置为true,为什么不在context里直接设置?参见观察者模式。
在ConextConfig的标准实现的applicationConfig中
private void applicationConfig() {
...
synchronized (webDigester) {
try {
URL url =
servletContext.getResource(Constants.ApplicationWebXml);
.....
}
servletContext为ApplicationContext的实例
public URL getResource(String path)
throws MalformedURLException {
DirContext resources = context.getResources();
if (resources != null) {
String fullPath = context.getName() + path;
// this is the problem. Host must not be null
String hostName = context.getParent().getName();
....
}
看到最后一行的getParent大家都明白了吧。
当然如果使用的是之前的SimpleContextConfig,就不需要Host了。
Engine
在tomcat中,Engine的标准实现是:org.apache.catalina.core.StandardEngine。
同样的Engine也有一个基础阀:StandardEngineValve
同是Engine不能再有父容器了,子容器也只能是Host。
StandardEngineValve
StandardEngineValve的invoke如下:
public void invoke(Request request, Response response,
ValveContext valveContext)
throws IOException, ServletException {
..........
// Select the Host to be used for this Request
StandardEngine engine = (StandardEngine) getContainer();
Host host = (Host) engine.map(request, true); //同样调用的是Containerbase的map
//addDefaultMapper 怎么来的就不用说//了吧
if (host == null) {
((HttpServletResponse) response.getResponse()).sendError
(HttpServletResponse.SC_BAD_REQUEST,
sm.getString("standardEngine.noHost",
request.getRequest().getServerName()));
return;
}
// Ask this Host to process this request
host.invoke(request, response);
}
验证了request与response后,就调用Containerbase的map获得一个Host,然后调用host的invoke。
How tomcat works 读书笔记十三 Host和Engine的更多相关文章
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- how tomcat works 读书笔记四 tomcat的默认连接器
事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...
- how tomcat works读书笔记 七 日志记录器
大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. packag ...
- how tomcat works 读书笔记(一)----------一个简单的webserver
http协议 若是两个人能正常的说话交流,那么他们间必然有一套统一的语言规则<在网络上server与client能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertex ...
- how tomcat works 读书笔记(一)----------一个简单的web服务器
http协议 若是两个人能正常的说话交流,那么他们间必定有一套统一的语言规则<在网络上服务器与客户端能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertext tran ...
- How Tomcat Works读书笔记三-------连接器
几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...
- How Tomcat Works 读书笔记 八 载入器 上
Java的类载入器 详细资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...
- How tomcat works 读书笔记十七 启动tomcat 下
在上一节中,我们程序的起始位置还是Bootstrap,现在我们通过bat文件来启动这个类. 在分析catalina.bat之前,我们先看看几个简单的我们能用到的dos命令. 基础知识 1 rem 注释 ...
- How tomcat works 读书笔记十七 启动tomcat 上
一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...
随机推荐
- 20 ViewPager Demo4自动轮播
MainActivity.java 思想:才用非常大的数 让其看起来可以循环轮播图片并且用户可以从尽头滑到首图的特点 . package com.qf.day20_viewpager_demo4; i ...
- [ExtJS5学习笔记]第三十一节 sencha extjs 5使用cmd生成的工程部署到tomcat服务器
本文地址:http://blog.csdn.net/sushengmiyan/article/details/42940883 本文作者:sushengmiyan ------------------ ...
- Linux命令—文件目录
(1) shell的使用 <1>检查系统当前运行的shell版本: [root@lab root]# echo $SHELL <2>从当前shell下切换到csh: [r ...
- Oracle 执行计划(Explain Plan) 说明
如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题. 如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以 ...
- UNIX网络编程——Socket/TCP粘包、多包和少包, 断包
为什么TCP 会粘包 前几天,调试mina的TCP通信, 第一个协议包解析正常,第二个数据包不完整.为什么会这样吗,我们用mina这样通信框架,还会出现这种问题? TCP(transport cont ...
- (NO.00004)iOS实现打砖块游戏(二):实现游戏主界面动画
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个内容不错的游戏也要一个好的包装.玩家进入游戏时第一眼看到的是 ...
- Docker教程:镜像构建和自动镜像构建dockerfile
http://blog.csdn.net/pipisorry/article/details/50805379 Docker透过Dockerfile来记录建立Container映象文件的每一个步骤,可 ...
- Unity 简易的UI背景昼夜轮替效果
在UI背景上实现一个简易的有光影照射的昼夜轮替效果,往往比一个死板的UI背景看起来更加形象生动,比较传统的方式是多图轮流替换的序列帧动画,不过要达到整个UI背景大图的所有地方都产生光影效果,那么务必每 ...
- x264 编码器选项分析 (x264 Codec Strong and Weak Points) 2
文章目录: x264 编码器选项分析 (x264 Codec Strong and Weak Points) 1 x264 编码器选项分析 (x264 Codec Strong and Weak Po ...
- 图文浅析Binder机制
总述: Binder是Android系统提供的一种IPC机制,Android系统基本就可以看做基于Binder的C/S架构,Binder也是C/S形式出现,它属于驱动但是驱动的一段内存而不是设备,框架 ...