Tomcat学习笔记其一

写在前面

  以下笔记来自于观看某老师关于Tomcat的讲解视频。因为水平有限和记录原因,笔记可能漏洞百出并杂乱无章。只能说一切仅供参考。

一句谚语

  我们常听到一句话“Tomcat是一个Servlet容器”

  那么如何理解这句话呢?

  Web项目中通常都会有Servlet,而Tomcat只认Servlet。

  用Java的形式翻译翻译Tomcat,就有了如下的类:

			class Tomcat{
				Connection conector;        // 请求处理
				List<Servlet> servlets;     // Servlet池
			}

  那么什么是Servlet呢?

​  Servlet说白了就是一种规范。

  Servlet == server + applet

  其中applet是java里一种古老的技术,表示用户可以用java语言写一个程序,而这个程序运行在浏览器上,就是运行在客户端上的程序。

  综上所述,Servlet就是运行在服务端上的程序。

看一段源码

protected void  doGet(HttpServletRequset req, HttpServletResponse resp) throws IOException{

    resp.getWriter().println("Hello,World");

}

  以上代码是某服务应用的doGet方法。我们发现其中的参数是接口类型的。

​  那么问题来了,是谁来实现这个接口的呢?这个实现类的实例是哪来的呢?

  ——是Tomcat实现这个接口。

  我们来理一下流程:

    用户在浏览器上提交数据->浏览器把请求发送给Tomcat服务器->Tomcat把数据封装为Request对象->tomcat.doGet(Requset 对象)

  这里留一个issue,因为tomcat.doGet调用的其实是RequestFacade对象。

RequestFacad与Tomcat的门面模式

​  Tomcat源码里,实现接口的最重要的两个类是:Request类和RequestFacade类。

  Facade代表的就是门面的意思。门面是对外的。

​  Request表示请求,是Tomcat里非常非常核心的类。而Request中有一些东西是Tomcat自己的,Tomcat不想把它们对外开放。

  于是就有了RequestFacade类。

  RequestFacade对象得到Request中的部分数据,同时把必要信息隐藏起来,让外界看不到。

  如此做法一来保护了Tomcat本身,二来更符合Servlet规范。外界少了干扰信息,也就能更加清楚调用请求了。

​  再回到上面的issue,就明白服务程序调用的请求对象其实是隐藏了Tomcat私密信息的RequestFacade。

细说容器

  回到那句话“Tomcat是一个Servlet容器”。

​  将这句话进行进一步解释,其实是如下的层次结构:

  Servlet->Wrapper->Context->Host->Engine

  这是一个大型套娃现场。

​  Wrapper是Servlet的容器,Context是Wrapper的容器,Host是Context的容器,Engine是Wrapper的容器。

  Context容器,Host虚拟地址,Engine主机。

  在这里重点讲Wrapper。

​  如果没有Wrapper,因为并发,所有的请求线程将公用一个Servlet实例。

  有了Wrapper后每个线程单独有一个Servlet实例。

  Wrapper把众多的Servlet放到Servlet池里。然后Context处理Wrapper的Servlet池。

  套娃的结构图如下:

管道与阀门

  从套娃结构图我们可以发现,每一层容器都有Pipeline管道。

​  那么Pipeline是干嘛的呢?

  Tomcat接收到请求后,请求会以Request对象的形式在管道里向下一层流。

  而管道里有很多阀门Value,Request对象每每流经一个阀门,就会触发相应的事件。比如执行某某日志的记录。

​  在最后的Wrapper层,管道里的Request对象变成了RequestFacade对象,然后RequestFacad对象被交与Servlet来进行服务程序的调用。

还有个Issue

  回到最上面的doGet例子。其实Tomcat没有直接调用Servlet里的方法,或者说Tomcat不是直接调用doGet方法。而是调用了Servlet的Service方法。

  Service方法是Servlet规范里的。它让Tomcat不必纠结于如何调用与调用哪个的问题。

​  可以这么说,不是Tomcat调用了服务的具体方法,而是Tomcat调用了服务的服务总管方法,服务总管再调用了具体方法。

posted @ 2020-03-04 22:02  萝卜熊  阅读(141)  评论(0编辑  收藏  举报