tomcat已经启动完成了,那么是怎么处理请求的呢?怎么到了我们所写的servlet的呢?

目录

  • Http11ConnectionHandler
  • Http11Processor
  • CoyoteAdapter
  • StandardEngineValve
  • StandardWrapperValve
  • 总结

Http11ConnectionHandler

在tomcat 启动之后会使用socket.accept接收请求,接收到之后会调用自己的processSocket来处理请求,在该方法中启动一个SocketProcessor线程,在该内部类的run方法内调用Http11ConnectionHandler.process,过程如下:

实际执行的是超类AbstractConnectionHandler.process方法,主要作用:

  • 从connections里面获取processor
  • 如果processor为null则尝试从队列里面获取一个processor,该队列是一个RecycledProcessors类继承自ConcurrentLinkedQueue,是一个线程安全的队列,因为同时会有多个线程获取processor
  • 如果processor还是为null(表明还未创建或者已经用完),那么创建一个新的processor,调用Http11ConnectionHandler.createProcessor,该方法会创建一个新的Http11Processor(但是并不会立即添加到上面提到的队列里面,而是在请求处理完成之后才会添加到队列里面)
  • 调用Http11Processor.process

Http11Processor

在connector出来完成之后会启动processor线程,关于processor的类图如下:

和处理协议一 一对应,不同的协议也有不同的processor,在AbstractProcessor里面有Request和Response,不过是org.apache.coyote包下面的,这是在connector层面的连接器,是primitive的。

实际执行的也是超类AbstractHttp11Processor.process,主要功能如下:

  • 获得socket的输入、输出流
  • parsing request header、method、requestURI
  • 设置input filters,并设置content-length等header
  • 调用CoyoteAdapter.service

CoyoteAdapter

由connector和processor过渡到container的类,使用了adapter模式,将container适配到processor。主要的方法就是CoyoteAdapter.service:

  • 获取org.apache.connector.Request和Response,这两个类经过facade模式之后就是最后我们servlet中使用的request和response
  • 如果是新建的processor,request和response为null,那么就调用connector.createRequest和createResponse新建,然后设置到coyote.request的note中
  • 调用postParseRequest,添加wrapper和servlet之间的映射(在后面load servlet的时候用到,request.setWrapper((Wrapper) request.getMappingData().wrapper);),parseSessionId解析sessionId
  • connector.getService().getContainer().getPipeline().getFirst().invoke(request, response),依次是:Connector,StandardService,StandardEngine,StandardPipeline,StandardEngineValve
  • 在执行完之后,完成请求也在这个方法中:request.finishRequest(上面说过的processor就是在这儿回收的),response.finishResponse(请求在这里返回到客户端,outputStream)
  • 最后,recycle request和response,清空request和response所有信息

StandardEngineValve

这个是StandardEngine的基础阀(每个容器都有一个pipeline,每个pipeline都有一个基础阀,用来调用servlet)在adapter中最后调用到了StandardEngineValve.invoke方法,该方法主要进行了以下操作

  • request.getHost:获取host
  • host.getPipeline().getFirst().invoke(request, response):依次是StandardHost,StandardPipeline,StandardHostValve

接下来就是容器逐级依次调用,下一个是StandardHostValve:

context.getPipeline().getFirst().invoke(request, response);

在接下来是NonloginAuthencator

context.invokeNext(request,response)

接着是StandardContextValve

 wrapper.getPipeline().getFirst().invoke(request, response);

接下来就是StandardWrapperValve,在这里进行了很多工作。

StandardWrapperValve

这是StandardWrapper的基础阀,作用就是获取servlet实例并调用filterChain,主要方法是invoke:

  • 获取容器wrapper,通过wrapper分配一个servlet实例
  • 使用ApplicationFilterFactory创建filterChain,web.xml配置的filter在这里加入到filter链中
  • filterChain.doFilter调用filter链,这里没有配置额外的filter,只有一个默认的WsFilter(对websocket的支持),在所有的filterChain调用完成之后,就是调用servlet.service 方法,开始进入我们写的servlet里面
  • 在上面调用完成之后,释放filterChain(将filter置空),释放servlet(会受到instantPool里面)

这个执行流程如上,最后一个UserServlet是我自定义的简单的servlet。到了自定义的servlet之后,依次请求也就是到了最深层,接下来就是逐层范返回,并做一些清理工作(当然了还有一些长连接的维护等等)。

总结

从socket监听接收开始,到我们自定义的servlet处理请求结束,是一次完整的请求过程,为了说明白请求的整个过程,省略了很多细节,比如:三种request(coyote.Request,connector.Request,RequestFacade)之间的转换,session的管理等等。

How Tomcat works — 六、tomcat处理请求的更多相关文章

  1. how tomcat works 六 生命周期

    我觉得这一章叫tomcat中的观察者模式,比较好! 首先,不要看本章,请查看一下关于观察者模式的资料比较好. 推荐以下知识点 基础篇 设计模式之禅----观察者模式 大家可以找到pdf阅读一下 另外本 ...

  2. How Tomcat Works(十六)

    本文接下来会介绍Host容器和Engine容器,在tomcat的实际部署中,总是会使用一个Host容器:本文介绍Host接口和Engine接口及其相关类 Host容器是org.apache.catal ...

  3. How Tomcat Works(六)

    本文继续分析HttpProcessor类,该类实现了org.apache.catalina.Lifecycle接口和java.lang.Runnable接口 我们先分析它的构造函数 /** * The ...

  4. How Tomcat Works(十七)

    在前面的文章中,已经学会了如何通过实例化一个连接器和容器来获得一个servlet容器,并将连接器和容器相关联:但在前面的文章中只有一个连接器可用,该连接器服务8080端口上的HTTP请求,无法添加另一 ...

  5. How Tomcat Works(十五)

    本文接下来分析Context容器,Context容器实例表示一个具体的Web应用程序,其中包括一个或多个Wrapper实例:不过Context容器还需要其他的组件支持,典型的如载入器和Session管 ...

  6. How Tomcat Works(十四)

    我们已经知道,在tomcat中有四种类型的servlet容器,分别为Engine.Host.Context 和Wrapper,本文接下来对tomcat中Wrapper接口的标准实现进行说明. 对于每个 ...

  7. How Tomcat Works(九)

    本文接下来描述servlet容器是怎样管理其相关组件的生命周期的,首先本人描述一下事件监听模式,也可以称为观察者模式,该模式分为以下角色 即抽象主题角色 具体主题角色 抽象观察者角色及具体观察者角色, ...

  8. How Tomcat Works(八)

    下面接着分析Context容器,该接口最重要的方法是addWrapper()方法与creatWrapper()方法,添加具体的子容器,这里是Wrapper容器实例 这里要分析的是一个简单的Contex ...

  9. How Tomcat Works(七)

    本文接下来介绍并分析servlet容器,servlet容器是用来处理请求servlet资源,并为web客户端填充response对象的模块. servlet容器是org.apache.catalina ...

随机推荐

  1. mysql操作--高级

    1.视图 2.储存过程 3.SQL编程

  2. sbt的assembly插件使用(打包所有依赖)

    1.sbt是什么 对于sbt 我也是小白, 为了搞spark看了一下scala,学习scala时指定的构建工具就是sbt(因为sbt也是用scala开发的嘛),起初在我眼里就是一个maven(虽然ma ...

  3. 建立自己的git repository

    环境是windows 1.首先安装Git,下载Git安装包,这个google 就好了 2.注册自己的git账号 https://github.com 3.建立仓库 填好名字 最后那个Initializ ...

  4. oracle 多级菜单查询 。start with connect by prior

    select * from S_dept where CODE in(select sd.code from s_dept sd start with sd.code='GDKB' connect b ...

  5. css小技巧之去掉蓝色底块的方法

    -moz-user-select: none; /*火狐*/ -webkit-user-select: none; /*webkit浏览器*/ -ms-user-select: none; /*IE1 ...

  6. java.lang.OutOfMemoryError: PermGen space及其解决方法(转载)

    java.lang.OutOfMemoryError: PermGen space及其解决方法 分类: java2007-09-11 12:34 162242人阅读 评论(51) 收藏 举报 gene ...

  7. 更换光纤后路由器端口映射 -VPN相关

    之前一直是ADSL的线路,使用路由器后,很简单就可以实现端口映射了!外网也可以随意连接,可是最近升级宽带更换了光纤后,发现怎么都不能正常工作了!在光纤猫里显示的IP居然是:10.0.*.*,查询到的外 ...

  8. 如何在命令行里运行python脚本

    python是一款应用非常广泛的脚本程序语言,谷歌公司的网页就是用python编写.python在生物信息.统计.网页制作.计算等多个领域都体现出了强大的功能.python和其他脚本语言如java.R ...

  9. js 图片预览

    图片预览 $('#pac_recipe').change(function() { var imgsrc = ''; ]) { //chrome firefox imgsrc = window.URL ...

  10. public <T> void show(T t),void前面的泛型T是什么作用

    public <T>这个T是个修饰符的功能,表示是个泛型方法,就像有static修饰的方法是个静态方法一样. <T> 不是返回值,表示传入参数有泛型 public static ...