引言
在进行web编程的时候常常使用tomcat作为servlet容器来使用,编写好servlet,配置好web.xml,启动tomcat后就可以通过浏览器输入网址就可以访问我们的项目了。有没有一刻想要弄清楚tomcat到底是如何实现这些功能的呢?
在我编写web程序的时候就有这么几个问题:
- 浏览器是如何与tomcat进行联系的呢?
- tomcat是如何通过我们配置的web.xml来装载servlet的呢?又是装在哪里的呢?
- 通过浏览器请求访问tomcat的资源又是怎么实现的呢?
带着这些问题我开始了对tomcat的源码分析。。。。
tomcat组成结构
前任栽树后人乘凉,在网络上我找到了这张tomcat组件结构图。可以看到整个tomcat的大致结构是这样的,首先有一个Server,接着Server里面可以有多个Service,在Service里面Connector和Container,并且还能看出在一个Service中Connector可以有1个或者多个但Container只有一个。
看到Connector和Container你是不是也想到了什么呢?没错Connector就是我们浏览器与tomcat进行联系的组件,Container就是装载servlet的组件。这两个组件是tomcat的核心组件,那么接下来我们就来看看Connector和Container的构成吧!!!
Connector组件构成
可以看到Connector中大概包括这样几个关键的组件:
Acceptor
通过名字就可以大概了解到这个组件的作用,Acceptor(接收者)用来接收浏览器的访问请求。这里大概介绍一下实现原理:通过serverSocket绑定监听端口,并开启接收,通过浏览器发起的请求就相当于发起了一次socket连接,连接这台电脑的8080端口。serverSocket接受连接后把它借给Processor处理
Processor
Processor通过这条连接读取请求的相关信息。这些信息包括 :1. 请求方法(get,post等等)——URL——协议/版本(如:HTTP/1.1)2. 请求头(包含客户端环境信息和请求实体正文的相关信息) 3. 请求实体(请求参数)。然后将这些信息使用Request对象装起来。(看到这里是不是会联想到servlet中的ServletRequest对象呢?但是他们并不相同。)
CoyoteAdapter
那么CoyoteAdapter又有什么作用呢?现在已经完成获得连接并读取请求信息,下一步就应该是找到请求的servlet并执行service方法了吧。。。。。
前面提到Request对象并不是servlet中service方法中需要的ServletRequest对象,所以CoyoteAdapter第一件要做的事情就是将Request对象中的信息提供给ServletRequest对象使用。做法是建立了一个新的Request类,这个类实现ServletRequest接口并关联了一个上面提到Request对象。接下来就是找到servlet并执行service方法了。。。。。CoyoteAdapter做的第二件事请就是将新的Request对象传递给Container,让Container来找到请求的servlet。
Container组件构成
可以看到Container主要包括这样几个组件:
Engine
一个Engine代表一个完整的Servlet引擎,它接收来自CoyoteAdapter的Request对象,并决定传给哪个Host来处理。
Host
Engine可以包含多个Host,每个Host代表一个虚拟主机,这个虚拟主机的作用就是运行多个应用,它负责安装和展开这些应用,并且标识这个应用以便能够区分它们,每个虚拟主机对应的一个域名,不同Host容器接受处理对应不同域名的请求。
Context
Host可以包含多个Context,Context是Servlet规范的实现,它提供了Servlet的基本环境,一个Context代表一个运行在Host上的Web应用
Wrapper
Context可以包含多个Wrapper, 一个Wrapper 代表一个 Servlet,它负责管理一个 Servlet,包括的 Servlet 的装载、初始化、执行以及资源回收。读取web.xml中的配置信息后,就会为一个个servlet生成一个Wrapper。
看了上面关于这些组件的介绍,我想还是有些摸不着头脑吧。那么我们从一个请求URL来具体的介绍一下这几个组件吧!!!
localhost:8080/day5/look
localhost 在URL中代表的是域名,在tomcat中代表的就是你请求的哪一个host(因为tomcat中允许有多个host)。
8080 是端口号,在tomcat中代表你连接的哪个Connector(这个端口号就是serverSocket监听的端口号)。
/day5/look 是请求的路径,通过这个路径就确定了你请求的哪个Context以及哪一个Wrapper。那么当CoyoteAdapter将解析
的请求信息传递给Container时,Container就可以找到你要访问的web项目的servlet了。