架构图
我们通过service.xml配置文件能看出来个大概
<Server>
<Listener/>
<GlobalNamingResources>
<Resource/>
</GlobalNamingResources>
<Service>
<Executor/>
<Connector/>
<Engine>
<Cluster/>
<Realm/>
<Host>
<Context/>
</Host>
</Engine>
</Service>
</Server>
为什么需要这么多组件,各个组件的作用是什么
其实要靠死记硬背记住这个架构还真不是容易的事,我们只有知道了为什么Tocat要这样设计,我们才能更好的记忆。那么要知道为什么要这样设计就需要知道这里面每个组件的作用是什么。
Server
Server代表整个catalina servlet容器。它的特性代表servlet容器的整体特性。Server可以包含一个或多个service。简单理解一个Server就是一个Tomcat实例。
service
一个Tomcat实例中可以有多个Service组件,它们彼此独立。一般我们用Tomcat的时候Service都只会配置一个,但其实Service是可以配置多个的。想象一下,如果需要在一个Tomcat里面部署两个名字相同的应用,应该怎么部署?下面演示了如何配置两个Service
Connector
Connector负责把接收到的请求解析出来然后封装成request和response对象然后交给Engine处理。目前Connector支持http和ajp协议。
Engine
Engine得到了处理请求后,会根据请求URL匹配Host.
Host
匹配到的Host会根据请求路径匹配Context,即在webapp下面找到相应的文件夹。
Context
Context负责匹配对应的Wrapper容器,一个Context可以理解为一个项目。
Wrapper
Wrapper容器是Tomcat中4个级别的容器中最小的,与之相对应的是Servlet,一个Wrapper对应一个Servlet。
举个例子
我们本机应用上启动了一个Tomcat,webapp下有我们部署的一个应用buxuewushu。我们在浏览器上输入http://localhost:8080/buxuewushu/add.do是如何找到对应Servlet进行处理呢?
在我们启动Tomcat的时候,连接器就会进行初始化监听所配置的端口号,这里我们配置的是8080端口对应的协议是HTTP。
- 请求发送到本机的8080端口,被在那里监听的HTTP/1.1的连接器Connector获得
- 连接器Connector将字节流转换为容器所需要的ServletRequest对象给同级Service下的容器模块Engine进行处理
- Engine获得地址http://localhost:8080/buxuewushu/add。匹配他下面的Host主机
- 匹配到名为localhost的Host(就算此时请求为具体的ip,没有配置相应的Host,也会交给名为localhost的Host进行处理,因为他是默认的主机)
- Host匹配到路径为/buxuewushu的Context,即在webapp下面找到相应的文件夹
- Context匹配到URL规则为*.do的servlet,对应为某个Servlet类
- 调用其doGet或者doPost方法
- Servlet执行完以后将对象返回给Context
- Context返回给Host
- Host返回给Engine
- Engine返回给连接器Connector
- 连接器Connector将对象解析为字节流发送给客户端
总结
可以看到tomcat虽然组件颇多,但其实各司其职。
connection负责处理请求与ServletRequest对象转换,转换完了交给Engine处理,Engine根据请求URL匹配具体的Host,Host又根据请求上下文匹配Context,也就是具体请求的项目,Context又会根据请求后缀匹配到Wrapper,也就是项目里具体的Servlet。