Tomcat学习笔记
Tomcat是什么
Tomcat是Servlet、JSP、java EL表达式、WebSocket的实现。
Tomcat 7.0实现了Servlet 3.0和JSP 2.2。提供了更多feature来开发和部署web应用和web服务。
官方资源汇总
编译源码
- 下载
Tomcat7源码 - 配置
JDK1.6 - 配置
1.9.x版本的Ant - 将build.xml中的
base-apache.loc.1=https://www.apache.org/dyn/closer.lua?action=download&filename=替换为base-apache.loc.1=https://archive.apache.org/dist - 在tomcat目录下执行
ant
源码阅读日志
整体理解
- 主类/主方法:
org.apache.catalina.startup包下的Bootstrap类。 - 几个重要的目录(或者说环境变量):
| 主目录 | 含义 |
|---|---|
| { $CATALINA_HOME } | Tomcat安装目录 |
| { $CATALINA_BASE } | 每个实例分别的根目录(可选,默认情况等同于{ $CATALINA_HOME }) |
CATALINA_HOME
├─bin // 诸如启动、停止等脚本。
├─conf // 配置文件
├─logs // 默认日志文件路径
└─webapps // web应用路径
架构理解
| 名称 | 意义 |
|---|---|
| Server | 代表整个容器。用户基本不会变动它。提供了Server接口。 |
| Service | 作为一个生存在Server中的组件,将许多Connector与一个Engine连接,起媒介作用。 |
| Engine | 代表某个Service的请求过程。一个Service连接着多个Conntector,Engine接收这些Connector的请求,处理请求,并返回。提供了Engine接口。 |
| Host | 一个Tomcat可包含多个域名,Host则维护这些域名。t提供了Host接口和完善的实现。 |
| Connector | 用于处理与客户端的通信。如Http Connector。 |
| Context | 代表一个Web应用。一个Host包含多个Context,分别处于唯一的路径。提供了Context和完善的实现。 |
按照以上概念可以绘图:

启动步骤
根据官方文档,tomcat启动序列分为两个步骤:1)从命令行启动 2)处理命令行参数
一、从命令行启动
类:org.apache.catalina.startup.Bootstrap
执行内容:
- 安装一系列
classLoader; - (以反射)读取启动类;
- 完成
Bootstrap.daemon.init()方法。
二、处理命令行参数(start,stop)
类:org.apache.catalina.startup.Bootstrap
执行内容(start):
Catalina.setAwait(true);Catalina.load():- 初始化基本文件夹:
initDirs()-> 设置诸如catalina.home/case等属性; - 初始化命名服务:
setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,org.apache.naming.java.javaURLContextFactory ->default) - 创建xml文件转化器:
createStartDigester() - 读取
server.xml并用转化器(digester)将其解析。digester是一个“XML-对象”映射器,将根据server.xml定义的内容创建对象。到目前为止,容器其实还没有开始初始化。 - 把
System.out和System.err分配给SystemLogHandler类。 - 调用所有组件的初始化方法。此步骤将令每个对象通过
JMX代理注册其本身。在此步骤中,Connector也将初始化适配器。适配器也是一种组件,用来执行请求预处理。例如HTTP1.1适配器:org.apache.coyote.http11.Http11Protocol
- 初始化基本文件夹:
Catalina.start():- 启动
NamingContext,将所有JNDI引用绑定其中。 - 启动
Server下的所有service。此步骤启动引擎(Engine)。 - 启动主机:
StandardHost。- 配置一个错误阀门,用于将不同的HTTP错误码为HTML。
- 设置标准主机阀门,将web应用的类加载器与线程上下文绑定,它也用来为请求找到相应的
session。 - 启动
HostConfig组件。此组件部署所有web应用,即webapp和conf/Catalina/localhost/*.xml HostConfig将为上下文创建一个Digester,它将调用ContextConfig.start()。这个方法将处理默认的web.xml即conf/web.xml,然后处理所有的应用web.xml即WEB-INF/web.xml。
- 在容器的生命周期中,存在一个后台线程,用来不断检查上下文(context)是否改变,即
war文件、context文件、web.xml文件等的改变。如果改变,则重新加载。(stop/remove/deploy/start)
- 启动
- 当Tomcat(在HTTP端口)接收到一个请求时:
- 该请求将被一个独立的线程接收。此线程在
ThreadPoolExecutor类中。它在一个ServerSocket.accpet()方法中等待请求。 ThreadPoolExecutor分配一个TaskThread来处理此请求。- 处理器(
processor)处理该请求。如果是HTTP请求,则是Coyote Http11Processor来处理。调用了process方法。此处理器将继续检查socket的输入流,直到连接断开,或者达到keep alive point。 - 此HTTP请求将被内部的缓冲类(
Http11InputBuffer)解析。此解析类将解析出请求行、请求头等等,将结果存储在一个Coyote请求中。此request包含所有的HTTP信息,如servername,port,scheme等。 - 处理器维护着一个
Adapter(引用),在本例中是CoyoteAdapter。一旦请求已经被解析,那么Http11Processor调用该adapter的service()方法。在此service方法中,Request包含一个CoyoteRequest和一个CoyoteResponse(第一次则为null)。CoyoteRequest(Response)实现了HttpRequest(Response)和HttpServletRequest(Response)。适配器通过Mapper来处理request和context等。 - 当解析完成之后,
CoyoteAdapter调用它的容器(StandardEngine),调用所有的invoke()方法。 StandardEngine.invoke()方法调用容器的pipeline.invoke()方法。StandardHostValve调用与request相关的context上的pipeline。- 被
Context pipeline调用的第一个阀门是FormAuthenticator阀门。接下来是StandardContextValve。StandardContextValve调用与context相关的所有上下文监听器。然后调用Wrapper组件的所有pipeline。 - 编译JSP,调用实际的
servlet。
- 该请求将被一个独立的线程接收。此线程在
servlet类的调用
优美代码
观察到,一个典型的类中,可以被分成:
// ------------------------------------------------------- Static Variables
// -------------------------------------------------------------- Variables
// -------------------------------------------------------- Private Methods
// ----------------------------------------------------------- Main Program
典型的生命周期方法有:
public void init()
public void init(String[] arguments)
public void start()
public void stop()
public void stopServer()
public void stopServer(String[] arguments)
public void destroy()
浙公网安备 33010602011771号