更正上一篇一个小错误,Connector中首先是将socket请求过来的信息封装成一个普通的Request对象(上一篇我写成HttpRequest对象,失误失误,根本就木有HttpRequest这样的对象。。。),然后在Adapter中封装成一个HttpServletRequest进行处理,再丢给Container。。。。

  源码中可以清晰的看到:

  ok,这一篇我们就来整个的看看tomcat源码,简单过一遍,看一看里面是怎么运行的(我也会删减大量的非核心的代码)

  在看源码之前,我想说一点废话,由于我也是菜鸟,所以大神勿喷啊!

  我自己在看别人分析源码博客的最深的体会就是,别人博客中分析那一段一段的简洁而明了的源码,也许我们看的时候感觉还是比较容易的,有点懂了,差不多了;但是有没有一种感觉,过不了几天就印象模糊了,再过几天就忘的差不多了,下次几乎又要重新学一遍,贼坑!知道为什么吗?因为我们看的只是别人分析后的结果,没看到别人分析的过程,为什么别人分析的过程这么简洁漂亮而自己分析就是一团糟?为什么要这么分析?从哪个方面切入的?假如我自己去分析源码能找到切入点吗?所以很多新人一想到自己要分析源码就头疼,不知道从哪里入手,脑子很迷糊!

  让我想起了一句话:谁知盘中餐,粒粒皆辛苦!我们在看着别人花费了几个小时甚至几天时间才总结出的源码,而我们看起来顶多几十分钟,没有自己亲自去辛苦,当然体会不深啊!所以要养成自己分析源码的能力和适合自己的方法很重要,就好像学习,学习的知识固然重要,但更重要的是学习的方法,因为知识可能会被淘汰,但是方法却能伴随你一生!

  咳,废话说多了,继续今天的内容吧!我们先来下载Tomcat源码,我下载的版本是7.0.92,下载路径:https://tomcat.apache.org/download-70.cgi

  注意不需要你原来的Tomcat版本和这个源码版本一致,随便下载一份源码就好

  下载之后解压,路径随意,但是我放在我的tomcat8目录里面

1.搭建IDEA导入Tomcat8源码的环境

  我们平常都是运行我们的web项目进行调试,我们是感受不到Tomcat的存在的,只有报错的时候才有可能看到tomcat的有关信息!所以我们要想个办法把Tomcat变成一个类似我们web项目一样的寻在,我们不就可以愉快的调试并且还可以随意修改其中的内容了嘛!

  首先进入上面下载的那个源码文件夹,新建一个catalina-home文件夹和pom.xml文件

  

  其中pom.xml里面的内容如下,可以直接进行复制

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.  
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>org.apache.tomcat</groupId>
  8. <artifactId>Tomcat8.5</artifactId>
  9. <name>Tomcat8.5</name>
  10. <version>8.5</version>
  11.  
  12. <build>
  13. <finalName>Tomcat8.5</finalName>
  14. <sourceDirectory>java</sourceDirectory>
  15. <testSourceDirectory>test</testSourceDirectory>
  16. <resources>
  17. <resource>
  18. <directory>java</directory>
  19. </resource>
  20. </resources>
  21. <testResources>
  22. <testResource>
  23. <directory>test</directory>
  24. </testResource>
  25. </testResources>
  26. <plugins>
  27. <plugin>
  28. <groupId>org.apache.maven.plugins</groupId>
  29. <artifactId>maven-compiler-plugin</artifactId>
  30. <version>2.3</version>
  31. <configuration>
  32. <encoding>UTF-8</encoding>
  33. <source>1.8</source>
  34. <target>1.8</target>
  35. </configuration>
  36. </plugin>
  37. </plugins>
  38. </build>
  39.  
  40. <dependencies>
  41. <dependency>
  42. <groupId>junit</groupId>
  43. <artifactId>junit</artifactId>
  44. <version>4.12</version>
  45. <scope>test</scope>
  46. </dependency>
  47. <dependency>
  48. <groupId>org.easymock</groupId>
  49. <artifactId>easymock</artifactId>
  50. <version>3.4</version>
  51. </dependency>
  52. <dependency>
  53. <groupId>ant</groupId>
  54. <artifactId>ant</artifactId>
  55. <version>1.7.0</version>
  56. </dependency>
  57. <dependency>
  58. <groupId>wsdl4j</groupId>
  59. <artifactId>wsdl4j</artifactId>
  60. <version>1.6.2</version>
  61. </dependency>
  62. <dependency>
  63. <groupId>javax.xml</groupId>
  64. <artifactId>jaxrpc</artifactId>
  65. <version>1.1</version>
  66. </dependency>
  67. <dependency>
  68. <groupId>org.eclipse.jdt.core.compiler</groupId>
  69. <artifactId>ecj</artifactId>
  70. <version>4.5.1</version>
  71. </dependency>
  72.  
  73. </dependencies>
  74. </project>

  然后我们打开我们新建的catalina-home目录

  然后我们进入IDEA,导入我们的源码项目(就是我们下载解压之后的那个文件夹)

  项目导入之后的目录应该这样的

  我们要配置一些运行参数(其实就是指定一下我们那几个复制的和新建的文件夹的路径)

  Main class(这个类很重要,是Tomcat的启动类):org.apache.catalina.startup.Bootstrap

  VM options(就是指定一些日志、工作文件夹等的路径):-Dcatalina.home=catalina-home -Dcatalina.base=catalina-home -Djava.endorsed.dirs=catalina-home/endorsed -Djava.io.tmpdir=catalina-home/temp -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=catalina-home/conf/logging.properties

  ok,再点击应用,就可以了,然后你可以右上角运行Tomcat,肯定会报错,就是一个Test类里面的什么Cookie错误,没啥用,你直接把那整个类都注释掉。(Ctrl+A全选。Ctrl+/注释);注意,可能会有个很低级的错误,就是提示你没有SDK或者JDK,你只需要在左上角file------>Project Structrue------->Project,在这里选择你的JDK版本,没有这个错误更好。

  然后你可以正常启动,但是在浏览器访问Tomcat的URL路径:localhost:8080又会报一个500的异常,原因是空指针异常,是一个什么JasperInitializer没有被加载,这个需要我们自己该一下源码手动让它加载。

  在IDEA中,Ctrl+N,搜一个ContextConfig的类,在下图的地方加入   context.addServletContainerInitializer(new JasperInitializer(),null);   这样就可以正常访问Tomcat主页了!

  其实到这里,基本的调试环境就搭建出来了,有兴趣的小伙伴可以Ctrl+N搜一下Bootstrap类,找到main方法,在init,load,start三个方法那里打断点进行调试啊,看看tomcat启动原理,我后面有时间的话也会一起看一看的!

2.简单从源码的角度看一看Tomcat组成

  还记得上一篇说的Tomcat的那些组成部分吗?这里还是大概理一下:

  Tomcat最核心的是conf/server.xml这个配置文件,这个配置文件中每个标签都代表一个Tomcat的组成部分,最外面的是一个server标签,其实可以简单的把这个server标签代表我们的Tomcat服务器,便于理解。一个Tomca实例t只有一个这个server标签

  次一级的就是service标签,这个标签可以配置多个,它是由两部分组成,connector和container

  其中connector可以配置多个, 分别为处理HTTP协议的和处理AJP协议的(至于还能不能处理其他的协议我也不怎么清楚,有时间研究一下),以Http的Connector为例,这个Connector里面就是一个协议处理器(ProtocolHandler),这个协议处理器里面由三部分组成:Endpoint(底层用socket接收客户端请求,并调用Processor处理),Processor(将用户的socket请求解析之后,包装成一个普通的Request对象和Response对象,再调用adaptor),Adaptor(就是将普通的Request和Response对象封装成HttpServletRequest对象,再想办法丢到Container中)

  Container里面是一个大容器里面套着小容器,小容器里面还有小容器的这样的一个结构,依次为Engine(一个Service只有一个),Host(可以多个),Context(可以多个),Wrapper(可以多个),当请求到了之后,会有一个管道---阀门机制,让这个请求从最外面的容器经过一道道阀门到最里面的容器,最后就到servlet的service方法运行,返回!

  接下来,我们就站在代码的角度,大概看看这些组成部分用代码是什么样子的,后面再说整个Tomcat的运行原理:

   首先是Connector,最重要的是一个有参构造:

 这里不得不说一句,你觉得tomcat是怎么处理通过HTTP协议或者AJP协议发来的请求的?难道每次都是把这个协议拿过来用正则表达式慢慢的拆开,分析吗?这也太lower了吧!而且我们关注的不应该是协议本身,而是之后的逻辑,所以Tomcat中就指定了一些处理每个协议的类,假如你用HTTP协议发过来的信息,Connector就会用反射去实例化HTTP协议处理器对你进行解析,然后我们还可以对协议处理器里面再进行很多处理,相比之前的用正则表达式慢慢解析,简直不要太牛!

  

  我们再进去协议处理器看看:

  同时,在Endpoint中有个内部类是Acceptor,用于监听客户端请求

  我们也来看看Connector里面的processor是个什么鬼

  进入到process里面

 这个service方法又在这个类里进行了重写

  最后我们就看看Adapter中的service方法是干什么了(貌似就在本篇最前面就截了service的这个图。。。。)

  这一篇就到这里了,看起来篇幅比较多,其实就是简单看了看Connector中各个组成部分的源码,下一节说说Container中的各个部分吧;最后应该会说一下整个Tomcat的启动流程!

知识小罐头06(tomcat8请求源码分析 中)的更多相关文章

  1. 知识小罐头07(tomcat8请求源码分析 下)

    感觉最近想偷懒了,哎,强迫自己也要写点东西,偷懒可是会上瘾的,嘿嘿!一有写博客的想法要赶紧行动起来,养成良好的习惯. ok,继续上一篇所说的一些东西,上一篇说到Connector包装了那两个对象,最后 ...

  2. 知识小罐头05(tomcat8请求源码分析 上)

    这一篇我们不看源码,就大概理一下Tomcat内部组成部分!前面花费了两篇博客的篇幅来说说了一般的maven web项目并部署到tomcat运行,其实都是为这篇做铺垫的! 其实我下载了tomcat7,t ...

  3. Tomcat处理HTTP请求源码分析(下)

    转载:http://www.infoq.com/cn/articles/zh-tomcat-http-request-2 很多开源应用服务器都是集成tomcat作为web container的,而且对 ...

  4. Tomcat处理HTTP请求源码分析(上)

    Tomcat处理HTTP请求源码分析(上) 作者 张华 发布于 2011年12月8日 | 8 讨论 分享到: 微博 微信 Facebook Twitter 有道云笔记 邮件分享 稍后阅读 我的阅读清单 ...

  5. # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#

    Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...

  6. Tomcat处理HTTP请求源码分析(上)(转)

    转载自:http://www.infoq.com/cn/articles/zh-tomcat-http-request-1 很多开源应用服务器都是集成tomcat作为web container的,而且 ...

  7. Okhttp同步请求源码分析

    进阶android,OKhttp源码分析——同步请求的源码分析 OKhttp是我们经常用到的框架,作为开发者们,我们不单单要学会灵活使用,还要知道他的源码是如何设计的. 今天我们来分析一下OKhttp ...

  8. SpringCloudGateway微服务网关实战与源码分析 - 中

    实战 路由过滤器工厂 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应.路由过滤器的作用域是特定的路由.SpringCloud Gateway包括许多内置的GatewayFilter ...

  9. 知识小罐头08(tomcat8启动源码分析 上)

    前面好几篇都说的是一个请求是怎么到servlet中的service方法的,这一篇我们来看看Tomcat8是怎么启动并且初始化其中的组件的? 相信看了前面几篇的小伙伴应该对Tomcat中的各个组件不陌生 ...

随机推荐

  1. (三)Maven使用入门之Hello World

    主要内容 编写POM 编写主代码 编写测试代码 打包和运行 到目前为止,已经大概了解并安装好了Maven,现在开始创建一个最简单的HelloWorld项目. 编写POM 就像Make的Makefile ...

  2. TestNG进行接口测试,脚本及可维护性框架

    注: 以下内容引自http://blog.csdn.net/u010321474/article/details/49977969 TestNG进行接口测试,脚本及可维护性框架 原创 2015年11月 ...

  3. Java 读书笔记 (十一) Number & Math 类

    所有的包装类(Integer.Long.Byte.Double.Float.Short)都是抽象类Number的子类. 这种由编译器特别支持的包装称为装箱,所以当内置数据类型被当作对象使用的时候,编译 ...

  4. TestNG 相对路径与绝对路径getResourceAsStream

    以下内容引自: http://blog.csdn.net/zmx729618/article/details/51144588 (注: 此url并非原出处,该文章也是转自他人.但博主未注明出处) Ja ...

  5. IZT复杂电磁环境记录回放和模拟系统

    结合实验室复杂电磁环境特性与模拟研究需求,实现对复杂多变的电磁环境录制.分析.重构和模拟,记录回放系统应具备如下几项能力: 1.电磁环境信号记录能力:能够实现对9KHz-18GHz频带范围内射频信号的 ...

  6. acl.go

    package acl   import ( "github.com/armon/go-radix" )   var ( // allowAll is a singleton po ...

  7. Java语言 链接Oracle数据库

    package com.tao.pojo; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pre ...

  8. 【STM32H7教程】第12章 STM32H7的HAL库框架设计学习

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第12章       STM32H7的HAL库框架设计学 ...

  9. 斯坦福CS224n课程作业

    斯坦福CS224n作业一 softmax 作业要求如下: 解析:题目要求我们证明\(softmax\)函数具有常数不变性. 解答:对于\(x+c\)的每一维来说,有如下等式成立: \[softmax( ...

  10. 再谈腾讯云centos服务器不能登录的解决过程

    上篇文章谈到腾讯云centos服务器不能登录,通过查看监控信息,cpu使用过高,再腾讯云页面使用VNC方式直接登录,然后根据提示信息,关闭导致内存溢出的进程,从而解决问题. 1 问题再现 昨天刚解决了 ...