Tomcat源码架构笔记(start启动篇)

warning: 这篇文章距离上次修改已过1409天,其中的内容可能已经有所变动。

上篇文章中,我们讲到了Tomcat启动时候的两大关键阶段之一的init初始化阶段,简单的走了一下初始化的流程。

  • init初始化阶段(传送门
  • start启动阶段

这里我们继续探究Tomcat start启动阶段的运行过程。


Tomcat start启动阶段

Tomcat start启动阶段Tomcat start启动阶段


启动流程开始

Bootstrap.main()Bootstrap.main()

调用Catalina.satrt()方法

Bootstrap.start()Bootstrap.start()

启动Server

Catalina.satrt()Catalina.satrt()

向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()

启动service子容器

StandardServer.startInternal()StandardServer.startInternal()

再次向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()


启动Engine子容器

info:开始走启动Engine的分支了

StandardService.startInternal()StandardService.startInternal()

再次向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()

调用父类startInternal方法

StandardEngine.startInternal()StandardEngine.startInternal()

循环启动线程池

线程池提交线程,如果有多个Host,那么就可以多个线程并行实例化Host,加快Tomcat启动速度

ContainerBase.startInternal()ContainerBase.startInternal()

StandardHostStandardHost

startChild核心逻辑

ContainerBase.StartChild()ContainerBase.StartChild()

再次向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()

调用父类startInternal方法

StandardHost.startInternal()StandardHost.startInternal()

Host实例化

Host的实例化,是通过设置容器生命周期状态(STARTING)。

通过触发Host生命周期事件fireLifecycleEvent来执行后续工作(实例化Context,交给HostConfig进行,HostConfig是生命周期事件监听器,触发对应事件)。

ContainerBase.startInternal()ContainerBase.startInternal()

触发start生命周期事件

LifecycleBase.setStateInternal()LifecycleBase.setStateInternal()

循环调用监听器

LifecycleBase.fireLifecycleEvent()LifecycleBase.fireLifecycleEvent()

监听器进行业务逻辑处理

HostConfig.lifecycleEvent()HostConfig.lifecycleEvent()

HostConfig.lifecycleEvent()调用start方法HostConfig.lifecycleEvent()调用start方法

部署webapp应用

HostConfig.start()HostConfig.start()

deployApps,处理Host下多个应用

HostConfig.deployApps()HostConfig.deployApps()

以多线程的方式处理Host下多个应用(目录模式)

deployDirectories,处理host下以目录方式部署的app-context

app处理的时候也是以多线程方式处理(results.add(es.submit(new DeployDirectory(this, cn, dir)));

HostConfig.deployDirectories()HostConfig.deployDirectories()

run方法

HostConfig.DeployDirectory()HostConfig.DeployDirectory()

webapp 部署的具体方法

HostConfig.deployDirectory()HostConfig.deployDirectory()

host.addChild(centext)时才去触发Context实例核心内容,比如wrapper-serlvet的封装

调用父类addChild方法

StandardHost.addChild()StandardHost.addChild()

进一步调用

ContainerBase.addChild()ContainerBase.addChild()

处理具体的Context

ContainerBase.addChildInternal()ContainerBase.addChildInternal()

具体的Context具体的Context

再次向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()

创建工作目录

StandardContext.startInternal()StandardContext.startInternal()

设置类加载器

StandardContext.startInternal()StandardContext.startInternal()

具体的读取web.xml封装wrapper

Context具体的读取web.xml封装wrapper过程使用事件驱动,交给了ContextConfig(它也是一个事件监听器)

StandardContext.startInternal()StandardContext.startInternal()

加载初始化Servlet

StandardContext.startInternal()StandardContext.startInternal()

findChildren值(计算表达式)findChildren值(计算表达式)

0,第一访问时加载;1,容器启动时加载;0,第一访问时加载;1,容器启动时加载;

判断是否在启动是加载初始化

StandardContext.loadOnStartup()StandardContext.loadOnStartup()

调用wrapper.load()

StandardContext.loadOnStartup()StandardContext.loadOnStartup()

实例化Servlet

StandardWrapper.load()StandardWrapper.load()

StandardWrapper.loadServlet()StandardWrapper.loadServlet()

findChildren值(计算表达式)findChildren值(计算表达式)


连接器启动

info:开始走连接器启动分支了

StandardService.startInternal()StandardService.startInternal()

向统一生命周期管理类报道

LifecycleBase.start()LifecycleBase.start()

PortocolHandler启动

Connector.startInternal()Connector.startInternal()

EndPoint初始化

AbstractProtocol.start()AbstractProtocol.start()

AbstractEndPoint.start()AbstractEndPoint.start()

NIO模型

NIO模型NIO模型

NioEndpoint.startInternal()NioEndpoint.startInternal()

创建Acceptor

NioEndpoint类NioEndpoint类

NioEndpoint.acceptor()NioEndpoint.acceptor()


OK,到此Tomcat的启动流程大概走完了,下一篇我们去看看Servlet处理请求的逻辑是什么样的。

评论已关闭