Tomcat--启动流程

Tomcat启动流程

在这里插入图片描述

过程:

  1. 启动Tomcat,需要调用bin/startup.bat(在linux目录下,需要调用bin/startup.sh),在startup.bat脚本中,调用了catalina.bat;
  2. 在catalina.bat脚本文件中,调用了BootStrap中的main方法;
  3. 在BootStrap的main方法中调用了init方法,来创建Catalina及初始化类加载器;
  4. 在BootStrap的main方法中调用了load方法,在其中又调用了Catalina的load方法;
  5. 在Catalina的load方法中,需要进行一些初始化的工作,并需要构造Digester对象,用于解析XML;
  6. 然后在调用后续组件的初始化操作。

Lifecycle

由于所有的组件均存在初始化、启动、停止等生命周期管理的特性,所以Tomcat在设计的时候,基于生命周期管理抽象成了一个接口Lifecycle,而Server、Service、Container、Executor、Connector组件都实现了一个生命周期的接口,从而具有以下生命周期中的核心方法:

  • init():初始化组件
  • start():启动组件
  • stop():停止组件
  • destroy():销毁组件

在这里插入图片描述

各组件的默认实现

上面我们提到的Server、Service、Engine、Host、Context都是接口,下图罗列了这些接口的默认实现类。当前对于Endpoint组件来说,在Tomcat中没有对应的ENdpoint接口,但是有一个抽象类AbstractEndpoint,其下有三个实现类:NioEndpoint、Nio2Endpoint、AprEndPoint,这三个实现类分别对应连接器支持的三种IO模型:NIO、NIO2和APR。

在这里插入图片描述

ProtocolHandler: Coyote协议接口,通过封装Endpoint和Processor,实现针对具体协议的处理功能。Tomcat按照协议和IO提供了6个实现类。

  • AJP协议:
    • AjpNioProtocol:采用NIO的IO模型
    • AjpNio2Protocol:采用NIO2的IO模型
    • AjpAprProtocol:采用APR的IO模型,需要依赖APR库
  • HTTP协议:
    • Http11NioProtocol:采用NIO的IO模型,默认使用的协议(如果服务器没有安装APR)
    • Http11Nio2Protocol:采用NIO2的IO模型
    • Http11AprProtocol:采用APR的IO模型,需要APR库

在这里插入图片描述

源码跟踪

BootStrap Main start,然后调用init()方法
init()方法主要是初始化类加载器、反射创建了一个Catalina对象实例。
在这里插入图片描述

BootStrap load:
BootStrap在init()后执行load()方法,在load()方法中反射调用catalina的load方法
在这里插入图片描述

Catalina load:
catalina的load()中创建了Tomcat的XML文件解析工具Digester,然后调用了Server的init()
在这里插入图片描述

Server init:
在Server的init()中又调用了Service的init方法
在这里插入图片描述

Service init:
在Service的init方法中主要做了三件事情:初始化engine、初始化executor、初始化connector
在这里插入图片描述

connector init:
在connector的init()中初始化了protocolHandler
在这里插入图片描述

protocolHandler init:
在protocolHandler的init()中调用了父类AbstractProtocol的init(),在其中调用了endpoint的init方法
在这里插入图片描述

endPoint init:
init中调用了bindWithCleanup()方法,bindWithCleanup()又调用了bind()。
在这里插入图片描述

endpoint bind:
endpoint.bind()调用了initServerSocket(),在initServerSocket()中进行端口等的绑定
在这里插入图片描述

BootStrap start:
Bootstrap的start()中反射调用了catalina的start():
在这里插入图片描述
catalina start:
catalina.strat()中调用了server的start方法:
在这里插入图片描述

server start
server.start()使用模板方法设计模式,调用了startInternal(),在实现类StandardServer中调用了service的init():
在这里插入图片描述

services start:
与init()类似,最终在StandardService的startInternal()中调用了engine、executor和connector的start()
在这里插入图片描述

connector start:
在Connector的startInternal()中调用了protocolHandler的start方法:
在这里插入图片描述

protocolHandler start:
在这里插入图片描述

endpoint start:
初始化一些栈,开启了接收线程:
在这里插入图片描述

startAcceptorThread()
在这里插入图片描述

总结

Tomcat的启动过程非常标准化,同一按照生命周期管理接口Lifecycle的定义进行启动。首先调用init()方法进行组件的逐级初始化操作,然后再调用start()方法进行启动。

每一级的组件除了完成自身的处理外,还要负责调用子组件响应的生命周期管理方法,组件与组件之间是松耦合的,因为我们可以很容易的通过配置文件进行修改和替换。

发布了892 篇原创文章 · 获赞 2314 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/105119903