聊聊Tomcat

话说Tomcat是一个Servlet容器吗?markdown

思考一下这句话,咱们能够抽象出来这么一段代码:app

class Tomcat {
    List<Servlet> sers;
}
复制代码

若是Tomcat就长这样,那么它确定是不能工做的,因此,Tomcat实际上是这样:spa

class Tomcat {
    Connector connector; // 链接处理器
    List<Servlet> sers;
}
复制代码

咱们这里先不考虑Connector的底层实现,咱们只需知道Connector是负责处理请求的。线程

咱们仍是来想一想容器。code

Context顾名思义

Servlet容器就是用来装载存储Servlet的。orm

一个Servlet表示一个运行在服务端的程序(servlet = server + applet)。用户想要使用这种程序,须要向该程序发送请求以及获取该程序的响应,也就是Servlet规范中的ServletRequest、ServletResponse。server

因此Servlet其实就是Java中用来处理请求的一种规范,因此咱们的项目中一般都会有一个或多个Servlet,由它来负责接收请求,或者将请求转交给其余业务逻辑。部署

因此咱们的Spring MVC、Spring Boot都存在一个DispatcherServlet(相似功能的一个Servlet,负责接收请求)。servlet

因此,一般Servlet是属于一个应用程序(项目)的,换句话说,咱们的一个应用包含多个Servlet,因此这是第二层Servlet容器--应用,也就是Tomcat中的Context(应用上下文)。那么第一层Servlet容器呢?域名

Wrapper

Wrapper就是第一层Servlet容器,Wrapper表示Servlet的包装者,因此它是最接近Servlet的,那么为何须要Wrapper呢?

咱们一般认为Wrapper是这样的:

class Wrapper {
	Servlet servlet;
}
复制代码

一个Wrapper对应一个Servlet,这么来想的话,确实不须要Wrapper,可是咱们还要考虑一些其余的状况:

  • 好比Filter,一个Filter是能够对应一个Servlet的。

  • 好比ServletPool,一般的Servlet是全部请求线程公用的,可是在Servlet中支持每个请求线程单独使用独立的Servlet实例。

因此在Wrapper中,不单单只包括一个Servlet,还包括过滤器和Servlet池,因此Wrapper是第一层Servlet容器。

Host

在咱们现实生活中,一个应用都是部署在一个主机上的,因此,一个主机能够包含多个应用,一个应用包含多个Servlet,因此,Host是第三层容器。

在Tomcat中,Host表示虚拟主机,Tomcat在处理请求时,能够根据请求的域名进入到相应的Host中进行处理。

Engine

Host管理Context,Context管理Wrapper,Wrapper管理Servlet,而Engine就是用来管理Host的。因此Engine是第四层容器。

最后

确定有人有疑问,那么Engine之上不须要容器了吗?不须要了?举个例子:

咱们的钱(Servlet)要放在钱包(Wrapper)里,钱包要放在书包(Context)里,书包要放在行李箱(Host)里,行李箱要放在飞机(Engine)上。

因此,若是你问我“Engine放哪?”就至关于问我“飞机放哪?”

答案是再也不须要更高层次的容器了,由于没有必要了。

总结

在Tomcat中,容器分为:

  1. Wrapper

  2. Context

  3. Host

  4. Engine