`
晨星★~雨泪
  • 浏览: 442181 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

TOMCAT源码分析(消息处理)

阅读更多
转至:http://blog.csdn.net/ThomasHuang/archive/2004/05/21/22394.aspx
0:前言
我们知道了tomcat的整体框架了, 也明白了里面都有些什么组件, 以及各个组件是干什么用的了。
http://www.csdn.net/Develop/read_article.asp?id=27225
我想,接下来我们应该去了解一下 tomcat 是如何处理jsp和servlet请求的。

1.  我们以一个具体的例子,来跟踪TOMCAT, 看看它是如何把Request一层一层地递交给下一个容器, 并最后交给Wrapper来处理的。
以http://localhost:8080/web/login.jsp为例子
(以下例子, 都是以tomcat4 源码为参考)

这篇心得主要分为3个部分: 前期, 中期, 和末期。
前期:讲解了在浏览器里面输入一个URL,是怎么被tomcat抓住的。
中期:讲解了被tomcat抓住后,又是怎么在各个容器里面穿梭, 最后到达最后的处理地点。
末期:讲解到达最后的处理地点后,又是怎么具体处理的。
2、  前期 Request的born.
    在这里我先简单讲一下request这个东西。
     我们先看着这个URL:http://localhost:8080/web/login.jsp  它是动用了8080端口来进行socket通讯的。
     我们知道, 通过
       InputStream in = socket.getInputStream() 和
       OutputStream out = socket.getOutputStream()
     就可以实现消息的来来往往了。
     但是如果把Stream给应用层看,显然操作起来不方便。
     所以,在tomcat 的Connector里面, socket被封装成了Request和Response这两个对象。
     我们可以简单地把Request看成管发到服务器来的数据,把Response看成想发出服务器的数据。
    
     但是这样又有其他问题了啊? Request这个对象是把socket封装起来了, 但是他提供的又东西太多了。
     诸如Request.getAuthorization(), Request.getSocket()。  像Authorization这种东西开发人员拿来基本上用不太着,而像socket这种东西,暴露给开发人员又有潜在的危险。 而且啊, 在Servlet Specification里面标准的通信类是ServletRequest和HttpServletRequest,而非这个Request类。 So, So, So. Tomcat必须得捣持捣持Request才行。 最后tomcat选择了使用捣持模式(应该叫适配器模式)来解决这个问题。它把org.apache.catalina.Request 捣持成了 org.apache.coyote.tomcat4.CoyoteRequest。 而CoyoteRequest又实现了ServletRequest和HttpServletRequest 这两种接口。 这样就提供给开发人员需要且刚刚需要的方法了。

    ok, 让我们在 tomcat的顶层容器 - StandardEngin 的invoke()方法这里设置一个断点, 然后访问
    http://localhost:8080/web/login.jsp , 我们来看看在前期都会路过哪些地方:
       1. run(): 536, java.lang.Thread, Thread.java
       CurrentThread
      2.  run():666, org.apache.tomcat.util.threads.ThreadPool$ControlRunnable, ThreadPool.java
               ThreadPool
       3.  runIt():589, org.apache.tomcat.util.net.TcpWorkerThread, PoolTcpEndpoint.java
          ThreadWorker
4.        processConnection():  549
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler, Http11Protocol.java
                  http protocol parser
      5.  Process(): 781, org.apache.coyote.http11.Http11Processor, Http11Processor.java
          http request processor
       6. service(): 193, org.apache.coyote.tomcat4.CoyoteAdapter,CoyoteAdapter.java
          adapter
       7. invoke(): 995, org.apache.catalina.core.ContainerBase, ContainerBase.java
   StandardEngin

    1. 主线程
    2. 启动线程池.
    3. 调出线程池里面空闲的工作线程。
    4. 把8080端口传过来由httpd协议封装的数据,解析成Request和Response对象。
    5. 使用Http11Processor来处理request
    6. 在Http11Processor里面, 又会call CoyoteAdapter来进行适配处理,把Request适配成实现了ServletRequest和HttpServletRequest接口的CoyoteRequest.
7. 到了这里,前期的去毛拔皮工作就基本上搞定,可以交给StandardEngin 做核心的处理工作了。

3. 中期。 在各个容器间的穿梭。
    Request在各个容器里面的穿梭大致是这样一种方式:
    每个容器里面都有一个管道(pipline), 专门用来传送Request用的。
    管道里面又有好几个阀门(valve), 专门用来过滤Request用的。
    在管道的低部通常都会放上一个默认的阀们。 这个阀们至少会做一件事情,就是把Request交给子容器。
    让我们来想象一下:
     当一个Request进入一个容器后, 它就在管道里面流动,波罗~ 波罗~ 波罗~ 地穿过各个阀门。在流到最后一个阀门的时候,吧唧~ 那个该死的阀门就把它扔给了子容器。 然后又开始 波罗~ 波罗~ 波罗~ ... 吧唧~....  波罗~  波罗~ 波罗~ ....吧唧~....
    就是通过这种方式, Request 走完了所有的容器。( 感觉有点像消化系统,最后一个地方有点像那里~  )
    OK, 让我们具体看看都有些什么容器, 各个容器里面又都有些什么阀门,这些阀们都对我们的Request做了些什么吧:

3.1 StandardEngin 的pipeline里面放的是:StandardEnginValve
在这里,VALVE做了三件事:
1.   验证传递过来的request是不是httpservletRequest.
2    验证传递过来的 request 是否携带了host header信息.
3    选择相应的host去处理它。(一般我们都只有一个host:localhost,也就是127.0.0.1)。
到了这个地方, 我们的request就已经完成了在Engin这个部分的历史使命, 通向前途未卜的下一站: host了。

3.2 StandardHost 的pipline里面放的是: StandardHostValve
1.   验证传递过来的request是不是httpservletRequest.
2.   根据Request来确定哪个Context来处理。
Context其实就是webapp, 比如http://localhost:8080/web/login.jsp
这里web就是Context罗!
3.   既然确定了是哪个Context了,那么就应该把那个Context的classloader付给当前线程了。
        Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());
   这样request就只看得见指定的context下面的classes啊, jar啊这些, 而看不见tomcat本身的类, 什么Engin啊, Valve啊。 不然还得了啊!
4. 既然request到了这里了,看来用户是准备访问web这个web app了,咋们得更新一下这个用户的session不是! Ok , 就由manager更新一下用户的session信息
5. 交给具体的Context 容器去继续处理Request.
6. Context处理完毕了,把classloader还回来。

3.3 StandardContext 的pipline里面放的是: StandardContextValve
1.   验证传递过来的request是不是httpservletRequest.
2.   如果request意图不轨,想要访问/meta-inf, /web-inf这些目录下的东西,呵呵,没有用D!
3.   这个时候就会根据Request到底是Servlet,还是jsp,还是静态资源来决定到底用哪种Wrapper来处理这个Reqeust了。
4.   一旦决定了到底用哪种Wrapper,OK,交给那个Wrapper处理。

4. 末期。 不同的需求是怎么处理的.
StandardWrapper
之前对Wrapper没有做过讲解,其实它是这样一种东西。
我们在处理Request的时候,可以分成3种。
处理静态的: org.apache.catalina.servlets.DefaultServlet 
处理jsp的: org.apache.jasper.servlet.JspServlet
处理servlet的: org.apache.catalina.servlets.InvokerServlet
不同的request就用这3种不同的servlet去处理。
Wrapper就是对它们的一种简单的封装,有了Wrapper后,我们就可以轻松地拦截每次的Request。也可以容易地调用servlet的init()和destroy()方法, 便于管理嘛!
具体情况是这么滴:
   如果request是找jsp文件,StandardWrapper里面就会封装一个org.apache.jasper.servlet.JspServlet去处理它。
   如果request是找 静态资源 ,StandardWrapper里面就会封装一个org.apache.jasper.servlet.DefaultServlet  去处理它。
   如果request是找servlet ,StandardWrapper里面就会封装一个org.apache.jasper.servlet.InvokerServlet 去处理它。

StandardWrapper同样也是容器,既然是容器, 那么里面一定留了一个管道给request去穿,管道低部肯定也有一个阀门(注1),用来做最后一道拦截工作.
在这最底部的阀门里,其实就主要做了两件事:
   一是启动过滤器,让request在N个过滤器里面筛一通,如果OK! 那就PASS。 否则就跳到其他地方去了。
   二是servlet.service((HttpServletRequest) request,(HttpServletResponse) response); 这个方法.
     如果是 JspServlet, 那么先把jsp文件编译成servlet_xxx, 再invoke servlet_xxx的servie()方法。
     如果是 DefaultServlet, 就直接找到静态资源,取出内容, 发送出去。
     如果是 InvokerServlet, 就调用那个具体的servlet的service()方法。
   ok! 完毕。
注1: StandardWrapper 里面的阀门是最后一道关口了。 如果这个阀门欲意把request交给StandardWrapper 的子容器处理。 对不起, 在设计考虑的时候, Wrapper就被考虑成最末的一个容器, 压根儿就不会给Wrapper添加子容器的机会! 如果硬是要调用addChild(), 立马抛出IllegalArgumentException!
参考:
     >
TOMCAT源码分析(启动框架)>
分享到:
评论

相关推荐

    基于SpringBoot框架的中小企业完全开源的ERP.zip

    基于springboot的java毕业&课程设计

    基于Springboot的健身信息系统.zip

    基于springboot的java毕业&课程设计

    基于vue + springboot的学生成绩管理系统.zip

    基于springboot的java毕业&课程设计

    基于卷积神经网络的语义分割

    基于卷积神经网络的语义分割卷积神经网络(Convolutional Neural Networks, CNNs 或 ConvNets)是一类深度神经网络,特别擅长处理图像相关的机器学习和深度学习任务。它们的名称来源于网络中使用了一种叫做卷积的数学运算。以下是卷积神经网络的一些关键组件和特性: 卷积层(Convolutional Layer): 卷积层是CNN的核心组件。它们通过一组可学习的滤波器(或称为卷积核、卷积器)在输入图像(或上一层的输出特征图)上滑动来工作。 滤波器和图像之间的卷积操作生成输出特征图,该特征图反映了滤波器所捕捉的局部图像特性(如边缘、角点等)。 通过使用多个滤波器,卷积层可以提取输入图像中的多种特征。 激活函数(Activation Function): 在卷积操作之后,通常会应用一个激活函数(如ReLU、Sigmoid或tanh)来增加网络的非线性。 池化层(Pooling Layer): 池化层通常位于卷积层之后,用于降低特征图的维度(空间尺寸),减少计算量和参数数量,同时保持特征的空间层次结构。 常见的池化操作包括最大池化(Max Pooling)和平均

    track-map_android-master.zip

    track-map_android-master

    dAFASFDSGSFDGFDHDFG

    dAFASFDSGSFDGFDHDFG

    毕设设计-学生宿舍管理系统 基于SpringBoot实现,界面简洁,功能完善

    毕设设计-学生宿舍管理系统 基于SpringBoot实现,界面简洁,功能完善 主要功能 ● 定位打卡、宿舍智能分配、学生信息管理、资讯管理(权限设计)等 使用 ● mysql、git、springboot ● 数据库初始化sql存储在doc文件夹下面 设计一个基于Spring Boot的学生宿舍管理系统,你需要确保系统既满足实用性,又保证界面简洁、功能完善。以下是一个基本的设计方案,包括系统的功能模块、技术栈选择和界面设计要点。 ### 功能模块 1. **用户认证模块**: - 登录/登出功能。 - 用户权限管理(如学生、宿舍管理员、系统管理员)。 2. **学生信息管理**: - 学生基本信息录入、查询、修改和删除。 - 宿舍分配与调换。 3. **宿舍楼管理**: - 宿舍楼信息维护。 - 宿舍房间信息管理。 4. **维修报修管理**: - 学生报修申请。 - 维修状态跟踪。 5. **来访登记管理**: - 来访人员登记。 - 访问记录查询。 6. **公告与通知发布**: - 发布宿舍相关公告和通知。

    课设毕设基于SSM的宝康药房销售管理系统 LW+PPT+源码可运行.zip

    课设毕设基于SSM的宝康药房销售管理系统 LW+PPT+源码可运行.zip

    python网络爬虫-入门基础学习爬虫原理.zip

    python网络爬虫-入门基础学习爬虫原理.zip

    PictureSelectDemo-master.zip

    PictureSelectDemo-master

    基于 YOLOv5 的实时摄像机馈送中识别对象-主体

    基于 YOLOv5 的实时摄像机馈送中识别对象-主体

    基于springboot的权限管理系统.zip

    基于springboot的java毕业&课程设计

    WBC白细胞数据集(300)

    该数据集大小为300张120×120地白细胞图片

    结构型设计模式(7种)

    结构型设计模式(7种)

    基于SpringBoot+SpringSecurity的RBAC管理系统.zip

    基于springboot的java毕业&课程设计

    MySQL8.4.0 LTS(mysql-test-8.4.0-linux-glibc2.17-aarch64.tar.xz)

    MySQL8.4.0 LTS(mysql-test-8.4.0-linux-glibc2.17-aarch64.tar.xz)适用于Linux Generic aarch64 glibc2.17

    GaodeMapDemo-master.zip

    GaodeMapDemo-master

    基于SSE和多核编程的电子相册设计与实现

    【作品名称】:基于SSE和多核编程的电子相册设计与实现 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:基于SSE和多核编程的电子相册设计与实现

    中国知网(cnki)爬虫及数据可视化分析设计 python毕业设计-源码+全部数据+使用文档(高分项目).zip

    中国知网(cnki)爬虫及数据可视化分析设计 python毕业设计-源码+全部数据+使用文档(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 【备注】 1、该项目是个人高分毕业设计项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(如软件工程、计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 中国知网(cnki)爬虫及数据可视化分析设计 python毕业设计-源码+全部数据+使用文档(高分项目).zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的。

    一种基于 STM32 的辅助分类变容垃圾桶.zip

    一种基于 STM32 的辅助分类变容垃圾桶.zip

Global site tag (gtag.js) - Google Analytics