Host

Host是Context的父容器。如果想在一个tomcat上部署多个context就需要使用Host了。上下文容器的父容器是主机,但是可能有一些其它实现,没有必要的时候也可以忽略。不过在实践中,即使是一个Context,我们也使用了Host,为什么?后面我们再说。

Host是个接口,里面有个map方法比较重要

  1. /**
  2. * Return the Context that would be used to process the specified
  3. * host-relative request URI, if any; otherwise return <code>null</code>.
  4. *
  5. * @param uri Request URI to be mapped
  6. */
  7. public Context map(String uri);

根据url来返回一个Context。

Host的标准实现是StandardHost

构造函数,不解释

  1. public StandardHost() {
  2. super();
  3. pipeline.setBasic(new StandardHostValve());
  4. }

StandardHost并没有invoke方法,它需要调用ContainerBase的invoke方法。

  1. //ContainerBase.java
  2. public void invoke(Request request, Response response)throws IOException, ServletException {
  3. pipeline.invoke(request, response);
  4. }

另外StandardHostValve这个基础阀会调用StandardHost的map方法获得一个context容器。

  1. public void invoke(Request request, Response response,
  2. ValveContext valveContext)
  3. throws IOException, ServletException {
  4. ....
  5. StandardHost host = (StandardHost) getContainer();
  6. //这里调用的是ContainerBase的map方法 最终会调用StandardHost的map方法(两个map方法没有关系 没有//复写 参数都不一样)
  7. Context context = (Context) host.map(request, true);
  8. ....
  9. }

StandHostMapper

在ContainerBase的start中有如下的代码

  1. addDefaultMapper(this.mapperClass);

看ConntainerBase

  1.  ContainerBase.java
  2. protected void addDefaultMapper(String mapperClass) {
  3. ......
  4. // Instantiate and add a default Mapper
  5. Class<?> clazz = Class.forName(mapperClass);
  6. Mapper mapper = (Mapper) clazz.newInstance();
  7. mapper.setProtocol("http");
  8. addMapper(mapper);
  9. ......
  10. }

这里我又一个小问题,为什么ContainerBase的start中的

addDefaultMapper(this.mapperClass);

调用的是子类中的addDefaultMapper呢?

  1. StandardHost.java
  2. protected void addDefaultMapper(String mapperClass) {
  3. // 参数默认为 "org.apache.catalina.core.StandardHostMapper";
  4. super.addDefaultMapper(this.mapperClass);
  5. }

StandardHost的start方法在结尾的时候会调用父类的start方法。



注意:Tomcat4 中的 standardContext 使用了不同的方法来创建一个默认映射器。它的 start 方法中并没有调用 super.start()。相反 Standardcontext 的start 方法调用 addDefaultMapper 来传递 mapperClass 变量。



StandardHostMapper的map方法就是调用StandardHost的map方法。

  1. public Container map(Request request, boolean update) {
  2. ...
  3. String uri = ((HttpRequest) request).getDecodedRequestURI();
  4. Context context = host.map(uri);
  5. ...
  6. return (context);
  7. }

在得到上下对象的时候需要一个往返过程,map 方法介绍两个参数,该方法是在 ContainerBase 中的。然后 ContainerBase 类又在它的子对象中查找合适的映射器并调用它的 map 方法。

StandardHostValve

这是Host的基础阀,什么时候注入的?大家自己想。



StandardHostValve这个基础阀会调用StandardHost的map方法获得一个context容器。

  1. public void invoke(Request request, Response response,
  2. ValveContext valveContext)
  3. throws IOException, ServletException {
  4. ....
  5. StandardHost host = (StandardHost) getContainer();
  6. //这里调用的是ContainerBase的map方法 最终会调用StandardHost的map方法(两个map方法没有关系 没有//复写 参数都不一样)
  7. Context context = (Context) host.map(request, true);
  8. ....
  9. HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
  10. String sessionId = hreq.getRequestedSessionId();
  11. if (sessionId != null) {
  12. Manager manager = context.getManager();
  13. if (manager != null) {
  14. Session session = manager.findSession(sessionId);
  15. if ((session != null) && session.isValid())
  16. session.access(); //修改session的最后访问时间
  17. }
  18. }
  19. context.invoke(request, response); //最后调用context的invoke
  20. }

为什么必须要有一个Host容器

想想我们之前的SimpleConextConfig,它的作用是将context的configured设置为true,为什么不在context里直接设置?参见观察者模式。

在ConextConfig的标准实现的applicationConfig中

  1. private void applicationConfig() {
  2. ...
  3. synchronized (webDigester) {
  4. try {
  5. URL url =
  6. servletContext.getResource(Constants.ApplicationWebXml);
  7. .....
  8. }

servletContext为ApplicationContext的实例

  1. public URL getResource(String path)
  2. throws MalformedURLException {
  3.  
  4. DirContext resources = context.getResources();
  5. if (resources != null) {
  6. String fullPath = context.getName() + path;
  7.  
  8. // this is the problem. Host must not be null
  9. String hostName = context.getParent().getName();
  10. ....
  11. }

看到最后一行的getParent大家都明白了吧。

当然如果使用的是之前的SimpleContextConfig,就不需要Host了。

Engine

在tomcat中,Engine的标准实现是:org.apache.catalina.core.StandardEngine。

同样的Engine也有一个基础阀:StandardEngineValve

同是Engine不能再有父容器了,子容器也只能是Host。

StandardEngineValve

StandardEngineValve的invoke如下:

  1. public void invoke(Request request, Response response,
  2. ValveContext valveContext)
  3. throws IOException, ServletException {
  4. ..........
  5.  
  6. // Select the Host to be used for this Request
  7. StandardEngine engine = (StandardEngine) getContainer();
  8. Host host = (Host) engine.map(request, true); //同样调用的是Containerbase的map
  9. //addDefaultMapper 怎么来的就不用说//了吧
  10. if (host == null) {
  11. ((HttpServletResponse) response.getResponse()).sendError
  12. (HttpServletResponse.SC_BAD_REQUEST,
  13. sm.getString("standardEngine.noHost",
  14. request.getRequest().getServerName()));
  15. return;
  16. }
  17.  
  18. // Ask this Host to process this request
  19. host.invoke(request, response);
  20. }

验证了request与response后,就调用Containerbase的map获得一个Host,然后调用host的invoke。

How tomcat works 读书笔记十三 Host和Engine的更多相关文章

  1. how tomcat works 读书笔记(二)----------一个简单的servlet容器

    app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...

  2. how tomcat works 读书笔记四 tomcat的默认连接器

    事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...

  3. how tomcat works读书笔记 七 日志记录器

    大家可以松一口气了,这个组件比较简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. packag ...

  4. how tomcat works 读书笔记(一)----------一个简单的webserver

    http协议 若是两个人能正常的说话交流,那么他们间必然有一套统一的语言规则<在网络上server与client能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertex ...

  5. how tomcat works 读书笔记(一)----------一个简单的web服务器

    http协议 若是两个人能正常的说话交流,那么他们间必定有一套统一的语言规则<在网络上服务器与客户端能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertext tran ...

  6. How Tomcat Works读书笔记三-------连接器

    几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是htt ...

  7. How Tomcat Works 读书笔记 八 载入器 上

    Java的类载入器 详细资料见 http://blog.csdn.net/dlf123321/article/details/39957175 http://blog.csdn.net/dlf1233 ...

  8. How tomcat works 读书笔记十七 启动tomcat 下

    在上一节中,我们程序的起始位置还是Bootstrap,现在我们通过bat文件来启动这个类. 在分析catalina.bat之前,我们先看看几个简单的我们能用到的dos命令. 基础知识 1 rem 注释 ...

  9. How tomcat works 读书笔记十七 启动tomcat 上

    一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让 ...

随机推荐

  1. Android简易实战教程--第十八话《ListView显示,简单的适配器SimpleAdapter》

    本篇介绍Listview的显示,对于listview有许多的适配器,如ArrayAdapter,BaseAdapter,SimpleAdapter等等.本篇先热身一下,介绍最简单的SimpleAdap ...

  2. Download all Apple open source OS X files at once

    While it is well known that Mac OS X contains open source code, how to access and download that sour ...

  3. 【Android应用开发】分享一个录制 Android 屏幕 gif 格式的小技巧

    因为写博客总是需要录制 Android 软件的演示效果, 研究了将近一小时找到了合适的工具; 录制流程 : -- 1. 录制 Android 手机屏幕内容 : 使用 拍大师 软件录制 Android ...

  4. android AlarmManager讲解

    Android系统闹钟定时功能框架,总体来说就是用数据库存储定时数据,有一个状态管理器来统一管理这些定时状态的触发和更新.在Andriod系统中实现定时功能,最终还是要用到系统提供的AlarmMana ...

  5. JQuery纵向下拉菜单实现心得

    jquery库给我们带来了许多便利,不愧是轻量级的DOM框架,在前面的博文中小编分别对jquery的基础知识以及jquery的一些小demo有一系列的简单介绍,期待各位小伙伴的指导.使用jquery实 ...

  6. android scrollview嵌套listview计算高度的问题

    ScrollView中只能放一个控件,一般都放LinearLayout,orientation属性值为vertical.在LinearLayout中放需要呈现的内容.ListView也在其中,List ...

  7. matlab中 mcc/mbuild/mex 区别

    mcc 的作用是将 .m文件编译为 c/c++动态链接库文件,使你可以在 c/c++程序中使用 matlab的一些函数功能.mcc 也可以将.m文件编译为exe可执行文件. mex 的作用是将 c/c ...

  8. String之常量池小结

    1.String 常量池 String使用private final char value[ ]实现字符串的存储,也就是说String创建对象之后不能够再次修改此对象中存储的字符串内容,因而Strin ...

  9. springMVC参数的传递方式(1.通过@PathVariabl获取路径参数,2.@ModelAttribute获取数据,3.HttpServletRequest取参,4@RequestParam)

     通过@PathVariabl注解获取路径中传递参数 JAVA      @RequestMapping(value = "/{id}/{str}")      public  ...

  10. 理解WebKit和Chromium: Android 4.4 上的Chromium WebView

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,原本基于Android Web ...