tomcat架构解析<1>

是的 ,最近有点忙 很长时间不看源码了
今天讲下 tomcat的整体架构和处理流程解析,我们都知道tomcat是一个servlet容器, 呢么问题来了,为什么要说tomcat是一个servlet容器
或者说这么说有什么理论依据
我先写一个servlet吧

在这里插入图片描述
在这里插入图片描述
我先写一个简单的servlet,然后吧他这个servlet打成war放到tomcat的webapp目录下 启动一下试试看
在这里插入图片描述
在这里插入图片描述
然后访问路径就可以查到我们的 hellow
此时

localhost:8080/testDemo/testDemo/
主机  :占用的端口/ 我的那个应用 /我的servlet

========================>

tomcat是一个web容器 这句话我们该怎么去理解
一个web 应用到底有那些方式部署到我们的tomcat上

基于这2个问题
在这里插入图片描述
此时我吧这个文件夹中的内容删了一部分,此时还是可以访问到我的servlet上的,发现war包解压后最后也是.class文件
呢么此时再抛一个问题 就是

	一个war 最后就是class
	一个jar 最后也是class
	似乎是一样的
	呢么此时我一个web应用打成jar扔到tomcat下就可以了, 
	为什么此时会打成war而扔到tomcat呢,而不直接打成jar呢
站在tomcat的角度上来结局这个问题 就是
我们知道.jar 在java中大多数情况都是一种依赖,
比如说是给别人用的,呢么我tomcat启动后 发现webapp目录下有一个
.jar ,他怎么判断 此时这个.jar是给别人用的呢 还是一个web项目
所以 tomcat就创建了.war  
也就是说 如果此时是一个.jar的话 我tomcat 不做处理 ,如果是一个.war的话
我就来部署他
如果说我看到这个文件是以.war结尾的 呢么我就对这个war进行部署

tomcat源码 底层就是这么写的 我不是道听途说啊
在这里插入图片描述
好了 问题回到上一层`

一个web 应用到底有那些方式部署到我们的tomcat上

结果是3个

在这里插入图片描述

现在 war包部署和文件夹部署都明白了吧 文件夹部署就是吧war进行解压
呢么 问题来了 描述符部署是啥

我们在学习servlet的时候除了吧war文件夹放到tomcat的webapp下,
我们还可以以另外一种方式来部署应用  我们可以写一个<context>节点

在这里插入图片描述
我每次打war的时候总会在target下生成这个文件夹
在这里插入图片描述

在tomcat中使用context节点部署工程	
我此时在tomcat的service.xml 配置这个Context,
  path表示访问这个项目的名字 ,docbase表示此时文件夹的路径 
  意思是通过路径找到项目内容 然后我去部署项目中内容

在这里插入图片描述
还是这个内容,当我们吧这个war放到tomcat的webapp下 此时我们相当于吧项目中的内容移动到了tomcat中 也就是说此时我手动吧项目中的内容移动到tomcat中
所以说此时对于tomcat来说 我只需要知道项目中的内容就可以了
也就是说此时的docBase 指向的是我war的地址

我用context节点代表
表示我此时定义一个应用[名字]  应用的内容就是 在docBase
所谓的内容要么通过文件夹/war找到项目内容
要么通过地址找到项目内容[项目的地址,这个项目下可以有很多Servlet ]

我找到你这个内容 然后我再部署你这个项目
Context 表示一个一应用 ,实质上在tomcat中是一个接口

在这里插入图片描述
所以说 此时Tomcat是一个Servlet容器

我们看看这个Container中的几个重要的容器

Context-----应用----容器
				List<Servlet>

在这里插入图片描述

在这里插入图片描述

3. Engine (自然讲Host也是需要管理的啊) 
		List<Host>管理虚拟主机
2.Host
	List<Context> //
	是Context 的父层节点 主要启的作用是将应用进行隔离
	localhost是虚拟主机 也就是我们访问的localhost
	此时再定义多个虚拟主机   同样的一个应用部署在 不同的虚拟主机
				根据域名判断---》虚拟主机--->找应用
				所以此时虚拟主机的目的就是将应用进行隔离
				进行解耦啊对吧,就是说将我们的请求基于业务下进行的拆分 或者说是基于应用来拆分(看图)
1.Context我也说了 
		List<Servlet>

在这里插入图片描述

唯一的难点就是在于这个wrapper
	wrapper 在host和Context中间
			一个Context 会有好多servlet
当一个Servlet实现了SingleThreadModel这个接口的时候,
,每一个请求都是一个实例,也就是说此时每一个请求都会配置一个Servlet
 如果不实现这个接口 代表所有请求公用一个Servlet
 如果此时使用 三层的话 代表我Context下面的Servlet很乱
 所以说此时单独抽象一个wrapper 
 这个wrapper实际上对应的就是 某一个Servlet类
这个wrapper 有2个属性
		属性	List<Servlet>
	    属性	Servlet[实现接口]
	    如果此时一个Servlet实现了SingleThreadModel 这个接口  就会用List<Servlet>
	    如果没有实现的话 就会用这个属性 意思是就只有一个Servlet实例
	   ===========================================>
	   而此时我Context 存 List<wrapper >

此时这也就是tomcat的容器架构图

在这里插入图片描述

 继续抛问题, 
 此时tomcat这么设计 吧这些东西分层了
呢么此时对于每一个容器
只是存了些对象的话并没有什么用
所以说此时会涉及到另外一个组件 叫做管道PipeLine(水管),管道中有很多阀门
value 阀门
此时在每一个容器里面都有一个管道
							
管道中真正重要的是这个阀门,这个阀门有自定义的,也有默认的
这些默认的阀门有一个重要的作用就是 相当于一个桥梁
将请求从Engine传到host上
所以说此时的 tomcat架构 

在这里插入图片描述

这个阀门类似于过滤器
在这里插入图片描述
在这里插入图片描述
好比此时我创建一个TestValve 在Host下配置 呢么此时请求经过localhost的这个主机的时候这个Value中的invoke方法
---------------------------------------------------------------->
总结一个版本
在这里插入图片描述
加入我现在有一个请求,tomcat首先会吧这个请求封装成request
然后吧这个请求交给Engine容器
在这里插入图片描述
在创建StandardEngine 这个实例的时候 会默认设置一个pipeline.setBasic(new StandardEngineValve());

此时这个Basic就是说将请求传递给Host ,这就是这个阀门实现的

每个Pipeline都是有特定的Valve,而且是在管道的最后一个执行,
这个Valve叫BaseValve,也就是此时的BaseValve  作用就是说将请求进行传递
呢么此时再抛一个问题,我定义一个Servlet就会有一个doget方法,呢么我这个doget方法
是谁来执行的,并且执行doget()我此时需要吧一个实现类传递给你

 呢么问题来了 这些接口的实现类是什么
	doget方法到底是谁来执行的
tomcat中有org.apache.catalina.connector.Request  这个类 但是

在调试servlet程序时,遇到调试窗口右上侧显示RequestFacade和ResponseFacade
此时tomcat这边用到了门面模式
也就是说此时 doget(request,response) 
传递的此参数是RequestFacade和ResponseFacade
因为此时tomcat不想吧某些东西暴露出来

在这里插入图片描述

 当我们的请求
		  走到最后面的阀门的时候	  这个阀门里面就会调用
		  wrapper----->生成一个servlet实例 然后调用value 	就会调用他这个doget()方法

在这里插入图片描述
此时servlet = wrapper.allocate(); 这里就吧servlet给我们找到了

猜你喜欢

转载自blog.csdn.net/weixin_43689953/article/details/109523933