博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tomcat源码学习探索笔记
阅读量:6904 次
发布时间:2019-06-27

本文共 2093 字,大约阅读时间需要 6 分钟。

hot3.png

现在tomcat源码量非常大,想读懂那么多人写的代码很耗时间,这里记下我学习tomcat的一点笔记

TomcatWeb服务器

几个月前我本科没毕业的时候,还不知道web服务器和应用服务器的区别

用我自己的话描述,自己的程序里带jar文件来支持JavaEE组件的是web服务器

socket开始

我觉得很多中间件源码读起来很困难,因为我们只看到了最终的产品,中间发展的过程以及增加的功能我们并不清楚.

Tomcat现在的源码量相当的大,即使读一些解读的文章再调试也不容易理解透彻,而且在业务团队里也没必要死抠每个技术细节,所以我觉得应该循序渐进

001003_9zf2_1449976.jpg

我先写一个最简单的Socket,启动时只要用浏览器访问 localhost:8080 就可以看到socket 传来的信息,并能看返回当前系统时间

收到的消息
001034_GDP9_1449976.jpg 

返回的结果

001107_G3fK_1449976.jpg

Socket改进

一个socket虽然很简单,但我们可以明白HTTP协议的原理

如果我们把它改进一下,input封装到Request,output封装到response,就好理解多了

001148_QVBd_1449976.jpg

我在github上找到一个挺有意思的东东

我稍微改动了一下这个代码,让它变得更直观些

它就是把我上面写的代码改成线程池管理,并把socket通过handler传给线程,分为RequestResponse,支持了本地文件的读写

001217_WUnp_1449976.jpg 

RequestHandler处理过程

001257_L8Sa_1449976.jpg 

执行效果

001323_rAFn_1449976.jpg

虽然和上面的代码相比不过就是封装了一下罢了

但线程池把socket监听请求以及io流的处理给分开了,其实这个过程就是tomcatconnectorcontainer通过HttpProcessor传递socket的过程的简化,Main里管线程池的代码我们可以封装到一个叫Connector里面,有请求就从池子里取个线程,让它合成RequestResponse,把它上交给.....容器

Classloader原理

其实做到上一步,基本可以把这坨代码当webServer跑了,但它不支持servlet,也没有webapps目录和Context,而且我们都是打war包的,war包里的那些类tomcat是怎么调用的?

因为tomcatclassloader是封装到Context里面的,这个加载过程不好解释,我就写一个简单的例子说明一下:

001405_YgsK_1449976.jpg

这个目录结构相当简单,folder下有个编译好的B,我们启动tomcat然后启动服务的过程可以视为Main类跑时把B类也加载进去

001500_dkyQ_1449976.jpg

为了更有说服力,我们可以先ps -ef|grep java 确定 folder不在我们的classpath里面

然后VM参数加上-verbose:class 亲眼看看B这个class文件是怎么被加载进去的

001525_lawP_1449976.jpg

在学校的时候配java环境变量,总是要把rt.jar 这堆玩意加到classpath,时间久了基本背下来要加哪些包了

Javaclassloader分为 bootstrap classloader,extension classloadersystem classloader,其实rt.jar里的那些java核心类就是bootstrap classloader给加进去的,我们可以执行以下这个代码看看bootstrap classloader都加载了什么

001613_VSaL_1449976.jpg

001648_ZHdl_1449976.jpg

Tomcat结构

写了这么多却一直没提tomcat有些三纸无驴的感觉,但其实写到这里,我们自己就能写个非常粗陋的支持servletwebServer类似物了

我学习tomcat源码不仅是因为好奇,为了方便定位问题,也是为了了解一点它的设计思想

我画了个草图,并按自己立即标注了一下这些组件是干啥的,大致说明一下tomcat的结构

001716_lZDJ_1449976.jpg

当然,这里面还有一些Loader, Pipeline ,Valve ,Repository 这类的小东西我没标,不然图就太乱了

由一个Socket突然变得这么复杂稍微有点过度不自然,也没关系,我在万能的github上又找到一个过度自然的项目

这个项目麻雀虽小五脏俱全,虽然没Server.xml配置文件,tomcat该有的它基本都有,只是容器只有ContextWrapper,但看懂这个基本就明白tomcat的设计思想了

这个项目下面有个Mushroom的项目,主项目跑起来,会把Mushroom放到Context容器里,并通过Loader加载里面编译好的class

这里没有filter,所以如果访问的uri直接能找到文件就直接返回文件内容,找不到就会从ContextValvemap里找加载好的Servlet然后invoke调用

这里面还有个LifeCycle接口,就是咱们常说的生命周期,每个容器都实现了这个接口里的方法

我读源码的办法

我是先debug,debug边看涉及到的类结构,因为这是多线程的,单纯debug不是很好理解

我把主要的类抠出来,只保留类里重要的域,debug一遍就能明白类之间的调用关系

001801_PNHi_1449976.jpg

001825_QHeY_1449976.jpg

转载于:https://my.oschina.net/tdONEmadao/blog/608256

你可能感兴趣的文章
需求分析--12章 过程建模
查看>>
C#运用实例.读取csv里面的词条,对每一个词条抓取百度百科相关资料,然后存取到数据库...
查看>>
css3选择器
查看>>
nginx虚拟主机配置
查看>>
PYthon基础
查看>>
delphi 把一个表的内容转到另一个表暂存时出错的解决方法。
查看>>
Android Studio 使用笔记:[转] Mac下修改Android Studio 所用的JDK版本
查看>>
《陶哲轩实分析》习题10.4.1
查看>>
【转载】浅析java中的语法糖
查看>>
Windows API 第21篇 DeleteVolumeMountPoint 删除挂载点
查看>>
CSS一些解决办法收集整理
查看>>
关于对char类型数据赋予负值的汇编表现
查看>>
润乾报表在proxool应用下的数据源配置
查看>>
DATABASE
查看>>
Python基础23_os,sys,序列化,pickle,json
查看>>
python MVC、MTV 框架介绍 Django 模板系统常用语法
查看>>
Day06
查看>>
C语言结构体在内存中的存储情况探究------内存对齐
查看>>
wamp版本升级小问题记录
查看>>
20161102学习笔记
查看>>