一、 Tomcat 源码分析
1 Tomcat 架构图
1.1 Server
Server 服务器的意思,代表整个 tomcat 服务器,一个 tomcat 只有一个 Server
Server 中包含至少一个 Service 组件,用于提供具体服务。这个在配置文件中也得到很好的体现(port=“8005” shutdown="SHUTDOWN"是在 8005 端口监听到"SHUTDOWN"命令,服务器就会停止)
1.2 Service
Service 中的一个逻辑功能层, 一个 Server 可以包含多个 Service
Service 接收客户端的请求,然后解析请求,完成相应的业务逻辑,然后把处理后的结果返回给客户端,一般会提供两个方法,一个 start 打开服务 Socket 连接,监听服务端口,一个 stop 停止服务释放网络资源。
1.3 Connector
称作连接器,是 Service 的核心组件之一,一个 Service 可以有多个 Connector,主要是连接客户端请求,用于接受请求并将请求封装成 Request 和 Response,然后交给 Container 进行处理,Container 处理完之后在交给 Connector 返回给客户端。
1.4 Container
Service 的另一个核心组件,按照层级有 Engine,Host,Context,Wrapper 四种,一个Service 只有一个 Engine,其主要作用是执行业务逻辑
1.5 Engine
一个 Service 中有多个 Connector 和一个 Engine,Engine 表示整个 Servlet 引擎,一个Engine 下面可以包含一个或者多个 Host,即一个 Tomcat 实例可以配置多个虚拟主机,默认
的情况下 conf/server.xml 配置文件中<Engine name="Catalina" defaultHost="localhost"> 定义了一个名为 Catalina 的 Engine。
一个 Engine 包含多个 Host 的设计,使得一个服务器实例可以承担多个域名的服务
1.6 Host
代表一个站点,也可以叫虚拟主机,一个 Host 可以配置多个 Context,在 server.xml 文件 中 的 默 认 配 置 为
<Host name="localhost" appBase="webapps" unpackWARs="true"autoDeploy="true">,
其中 appBase=webapps, 也就是<CATALINA_HOME>\webapps 目录,
unpackingWARS=true 属性指定在 appBase 指定的目录中的 war 包都自动的解压,
autoDeploy=true 属性指定对加入到 appBase 目录的 war 包进行自动的部署。
1.7 Context
Context,代表一个应用程序,就是日常开发中的 web 程序,或者一个 WEB-INF 目录以及下面的 web.xml 文件,换句话说每一个运行的 webapp 最终都是以 Context 的形式存在,每个 Context 都有一个根路径和请求路径;与 Host 的区别是 Context 代表一个应用,如,默认配置下 webapps 下的每个目录都是一个应用,其中 ROOT 目录中存放主应用,其他目录存放别的子应用,而整个 webapps 是一个站点。
2 Tomcat 启动源码分析
2.1 启动流程
tomcat 的启动流程很标准化,入口是 BootStrap,统一按照生命周期管理接口 Lifecycle的定义进行启动。首先,调用 init()方法逐级初始化,接着调用 start()方法进行启动,同时,每次调用伴随着生命周期状态变更事件的触发。
2.2 启动文件分析
1、解析 Startup.bat
最终定位执行catalina.bat
2、解析 catalina.bat
set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%\bin\bootstrap.jar"
set MAINCLASS=org.apache.catalina.startup.Bootstrap
setACTION=start
3 Bootstrap
main 方法是整个 tomcat 启动时的入口。在 main 方法中,使用 bootstrap.init()来初始化类加载器和创建 Catalina 实例,然后再启动 Catalina 线程
3.1 bootstrap.init() 方法
用 于 初 始 化 容 器 相 关 , 首 先 创 建 类 加 载 器 , 然 后 通 过 反 射 创 建org.apache.catalina.startup.Catalina 实例。
4 Catalina
4.1 Lifecycle 接口
Lifecycle 提供一种统一的管理对象生命周期的接口。通过 Lifecycle、LifecycleListener、LifecycleEvent,Catalina 实现了对 tomcat 各种组件、容器统一的启动和停止的方式。
在 Tomcat 服 务 开 启 过 程 中 启 动 的 一 些 列 组 件 、 容 器 , 都 实 现 了org.apache.catalina.Lifecycle 这个接口,其中的 init()、start() 方法、stop() 方法,为其子类实
现了统一的 start 和 stop 管理
4.2 load 方法解析 server.xml 配置文件
load 方法解析 server.xml 配置文件,并加载 Server、Service、Connector、Container、Engine、Host、Context、Wrapper 一系列的容器。加载完成后,调用 initialize()来开启一个新的 Server
4.3 Digester 类解析 server.xml 文件
利用 Digester 类解析 server.xml 文件,得到容器的配置。
4.4 demon.start()
demon.start()方法会调用 Catalina 的 start 方法
Catalina 实例执行 start 方法。这里有两个点,一个是 load()加载 server.xml 配置、初始化 Server 的过程,一个是 getServer().start()开启服务、初始化并开启一系列组件、子容器的过程
5 StandardServer
5.1.1 service.initialize()
然后拿到 StandardServer 实例调用 initialize()方法初始化 Tomcat 容器的一系列组件。一些容器初始化的的时候,都会调用其子容器的 initialize()方法,初始化它的子容器。顺序是
StandardServer、StandardService、StandardEngine、Connector。每个容器都在初始化自身相关设置的同时,将子容器初始化。