Tomcat学习——启动流程源码跟踪

我们知道在java编程中,每个对象都是有生命周期的。
在tomcat中,由于所有的组件均存在初始化、启动、停止等生命周期方法,拥有生命周期管理的特性,所以Tomcat在设计的时候,基于生命周期管理抽象成了一个接口Lifecycle,而Server、Service、Container、Executor、Connector组件,都实现了该接口,从而具有了init、start、stop、destroy等生命周期中的方法。

Lifecycle.png

先来看一张启动过程时序图,了解一下启动顺序:
启动时序图.png

Tomcat启动的入口类:org.apache.catalina.startup.Bootstrap类的main()方法

main方法是整个tomcat启动时的入口。在main方法中,使用bootstrap.init()来初始化类加载器和创建Catalina实例,然后再启动Catalina线程。

bootstrap.init()方法,用于初始化容器,首先创建类加载器,然后通过反射创建Catalina实例:


然后在Bootstrap类的main()方法再调用Bootstrapload()方法,在load()方法中通过反射来调用Catalinaload()方法


Catalinaload()方法先去解析Tomcat的Server.xml配置文件,然后会去调用serverinit()方法
解析server.xml配置文件

调用serverinit()方法

此处使用了模板方法设计模式,最终调用的是实现类org.apache.catalina.core.StandardServerinitInternal()方法,在该方法中又调用了Serviceinit()方法,并且是在for循环中调用的,也就验证了一个Server中可以多个Service

跟上面一样,调用serviceinit方法最终调用的是实现类org.apache.catalina.core.StandardServiceinitInternal()方法,在该方法中主要完成三件事:
1、初始化Engine
2、初始化Executor
3、初始化Connector


EngineExecutor的初始化代码,都是类似的,就是向下一级一级调用init方法,来初始化对应的组件,这里我们就不再继续跟踪了,我们接下来跟踪一下Connector的初始化代码。
Connector并不是接口,本身就是一个实现类,所以它的init方法调用的就是org.apache.catalina.connector.Connector类的initInternal()方法,在此方法中创建了CoyoteAdapter对象,用于将Request对象转换成ServletRequest对象,再调用容器来处理请求,最后调用ProtocolHandlerinit方法

调用ProtocolHandlerinit方法时,根据我们使用的http协议,最终调用的是实现类org.apache.coyote.http11.AbstractHttp11Protocolinit()方法,而其中又调用的是父类org.apache.coyote.AbstractProtocolinit()方法,在其中又调用了Endpoint的初始化方法

最终调用的是org.apache.tomcat.util.net.NioEndpointbind()方法,在其中开启Socket连接,并绑定监听的端口


至此,初始化init流程就结束了。接下来我们再来看start流程,再次回到刚开始的Bootstrapmain方法中
load()方法之后紧接着调用Bootstrapstart()方法

Bootstrapstart()方法中,同样是利用反射调用Catalinastart()方法

Catalinastart()方法中,又调用了Serverstart()方法


Serverstart()方法中循环调用了每个Servicestart()方法,然后在Servicestart()方法中做了三件事
1、调用Enginestart()方法
2、调用Executorstart()方法
3、调用Connectorstart()方法
此处的代码我就不贴出来了,可以自己去跟踪查看,我们来看看Connectorstart()方法,在其中调用了ProtocolHandlerstart()方法,最终调用的是实现类org.apache.coyote.AbstractProtocolstart()方法,在该方法中又调用了org.apache.tomcat.util.net.NioEndpointstartInternal()方法
而在NioEndpointstartInternal()方法中最后调用了父类org.apache.coyote.AbstractProtocolstartAcceptorThreads()方法,在其中创建并开启线程来接收客户端请求

我们来看看Acceptor中的run()方法


至此,Tomcat启动流程就结束了

你可能感兴趣的:(Tomcat学习——启动流程源码跟踪)