Tomcat 源码分析(二)——Request处理全过程
前一篇博客,我总结了Tomcat对于生命周期组件的管理。在了解了容器的启动之后,我们开始剖析它的内部运行机制。今天我们来分析一下Tomcat如何处理Request。Socket作为网络通信的基础也是Request和Response的底层实现,有过Socket使用经验的读者一定不会对下面的伪代码陌生:
// Java伪代码
...
while(true) {
Socket soc = ServerSocket.accept(); // 监听并阻塞
new Thread(new Runnable() { // 开辟新的线程处理Socket
inputStream(soc); // 读取Socket中的数据
outputStream(soc); // 写入数据
});
}
...
一、从Socket到Request
Tomcat容器对Socket的处理思路与以上伪代码基本一致,只是更加复杂。下图展示了从Tomcat启动到Socket到来后,主要类的调动过程(虚线箭头表示有新的线程启动):
Acceptor是定义在JIoEndpoint中的内部类实现了Runnable接口。在run方法中定义了循环语句while (running){...}重点是ServerSocketFactory获取监听端口(默认8080)上的Socket请求
Socket socket = null;
try {
// Accept the next incoming connection from the server
// socket
socket = serverSocketFactory.acceptSocket(serverSocket);
...
然后,这个Socket对象会被封装成SocketWrapper对象并交给给JIoEndpoint的另一个内部类SocketProcessor处理。
protected boolean processSocket(Socket socket) {
// Process the request from this socket
try {
SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
wrapper.setSecure(isSSLEnabled());
...
一直到AbstractHttp11Processor.process方法,我们第一次见到了Request的身影。不过此时的Request实际上是org.apache.coyote.Request,它是Tomcat内部的定义类并且被final修饰。在CoyoteAdapter.service方法中,它又被处理成:org.apache.catalina.connector.Request,它继承了HttpServletRequest。直到这时,从Socket到Request才真正完成。
二、Pipeline、FilterChain以及设计模式
ContainerBase是Tomcat中的生命周期组件。它包含了4个标准的实现类:StandardContext、StandardEngine、StandardHost和StandardWrapper。每一个Container对象都含有各自的Pipeline和Valve。
/**
* The Pipeline object with which this Container is associated.
*/
protected Pipeline pipeline = new StandardPipeline(this); /**
* Create a new StandardContext component with the default basic Valve.
*/
public StandardContext() { super();
pipeline.setBasic(new StandardContextValve());
...
}
...
它们通过Container的构造函数被初始化,并负责处理Request。每一个Containner组件都实现了各自的invoke方法,具体的业务逻辑读者可以自己去分析。
经过4次invoke,Request会继续交给FilterChain(责任链模式的核心对象)处理。
ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet); try {
if ((servlet != null) && (filterChain != null)) {
if (context.getSwallowOutput()) {
...
} else {
if (request.isAsyncDispatching()) {
...
} else if (comet) {
...
} else {
filterChain.doFilter(request.getRequest(), response.getResponse());
}
}
...
经过多个Filter的处理,才会交到Servlet的手中。
Tomcat 源码分析(二)——Request处理全过程的更多相关文章
- Tomcat源码分析二:先看看Tomcat的整体架构
Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...
- Tomcat 源码分析(转)
本文转自:http://blog.csdn.net/haitao111313/article/category/1179996 Tomcat源码分析(一)--服务启动 1. Tomcat主要有两个组件 ...
- Tomcat源码分析三:Tomcat启动加载过程(一)的源码解析
Tomcat启动加载过程(一)的源码解析 今天,我将分享用源码的方式讲解Tomcat启动的加载过程,关于Tomcat的架构请参阅<Tomcat源码分析二:先看看Tomcat的整体架构>一文 ...
- [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat
概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...
- Tomcat源码分析(二)------ 一次完整请求的里里外外
Tomcat源码分析(二)------ 一次完整请求的里里外外 前几天分析了一下Tomcat的架构和启动过程,今天开始研究它的运转机制.Tomcat最本质就是个能运行JSP/Servlet的Web ...
- Tomcat源码分析--转
一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...
- Tomcat源码分析
前言: 本文是我阅读了TOMCAT源码后的一些心得. 主要是讲解TOMCAT的系统框架, 以及启动流程.若有错漏之处,敬请批评指教! 建议: 毕竟TOMCAT的框架还是比较复杂的, 单是从文字上理解, ...
- Tomcat源码分析 (四)----- Pipeline和Valve
在 Tomcat源码分析 (二)----- Tomcat整体架构及组件 中我们简单分析了一下Pipeline和Valve,并给出了整体的结构图.而这一节,我们将详细分析Tomcat里面的源码. Val ...
- tomcat源码--springboot整合tomcat源码分析
1.测试代码,一个简单的springboot web项目:地址:https://gitee.com/yangxioahui/demo_mybatis.git 一:tomcat的主要架构:1.如果我们下 ...
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
随机推荐
- thinkphp3.2.3使用ajax 的一些坑——使用AjaxReturn()后,直接返回null,模板文件不起作用
从接触thinkphp到今天,填完此坑,必有其他的坑有会冒出来.哎!这个填坑之路我想是没有尽头的了. 最近,需要使用ajax完成一些操作,一开始想Ajax简单啊,不过是一种提交数据的方式,不过是害苦了 ...
- C# 控件拖动
https://zhidao.baidu.com/question/2116834779399609987.html [DllImport("user32.dll", EntryP ...
- Django内置Admin
Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.contrib.contenttyp ...
- longest valid parentheses方法归纳
题目大意见leetcode,下面我稍微介绍下想到的三种方法: 方法一:不用栈去找匹配 建立一个数组l2表示匹配,然后i从0开始,看到 ( 就把l2对应的数值记为-1,直到看到 ),找到)以后,从当前i ...
- python如何玩“跳一跳”!(windows安桌版本请进!)
最近"跳一跳",很火爆,有木有? 看了一下网上的教程,动作搭建了一下环境,就可以用脚本自动跑起来啦!!! 下面说一下android手机的实现过程: 首先,是python环境的搭建 ...
- ERP报错:所在的期间无效,但又无法新增账套期间。
问题: 进入2018新年月,客户在新增单据的时候,报错:日期[2018-01-03]所在的期间无效 正常解决方法 过账期间里面设置一下路径:管理----期间与结账----过账期间设置 先设置年期间-- ...
- 5分钟了解MySQL5.7的undo log在线收缩新特性
Part1:写在最前 在MysQL5.6版本中,可以把undo log 回滚日志分离到一个单独的表空间里:其缺点是不能回收空间大小,until MysQL5.7,but MariadDB10.1暂不支 ...
- Jenkins+Gitlab CE+Robot Framework持续集成
环境 Ubuntu 14.04.3 LTS Desktop 前提 1.在本地能执行测试脚本(pybot yourTestSuit.txt),本文不讲解如何学习使用RF框架 2.已有Gitlab环境,本 ...
- 微信小程序之实现slideUp和slideDown效果和点击空白隐藏
怎样实现jq中的slideUp或者slideDown这种动画效果呢,我的思路是用css3的transform: translateY()属性,给需要动画的元素添加上一个动画class. 先上效果图: ...
- CSS基础知识(颜色、伪类、盒子模型)
6.设置颜色单位 L 普通英文单词 {color : 属性值red;} 此方法简单,便捷.但设置的颜色在不同浏览器中,可能显示的颜色出现差异 * 三原色 - 红.绿.蓝 L 颜色的八进制方式 ...