Tomcat源码架构笔记(start启动篇)
warning:
这篇文章距离上次修改已过2000天,其中的内容可能已经有所变动。
在上篇文章中,我们讲到了Tomcat启动时候的两大关键阶段之一的init初始化阶段,简单的走了一下初始化的流程。
- init初始化阶段(传送门)
- start启动阶段
这里我们继续探究Tomcat start启动阶段的运行过程。

Tomcat start启动阶段
Tomcat start启动阶段启动流程开始
Bootstrap.main()调用Catalina.satrt()方法
Bootstrap.start()启动Server
Catalina.satrt()向统一生命周期管理类报道
LifecycleBase.start()启动service子容器
StandardServer.startInternal()再次向统一生命周期管理类报道
LifecycleBase.start()启动Engine子容器
info:开始走启动Engine的分支了
StandardService.startInternal()再次向统一生命周期管理类报道
LifecycleBase.start()调用父类startInternal方法
StandardEngine.startInternal()循环启动线程池
线程池提交线程,如果有多个Host,那么就可以多个线程并行实例化Host,加快Tomcat启动速度
ContainerBase.startInternal()
StandardHoststartChild核心逻辑
ContainerBase.StartChild()再次向统一生命周期管理类报道
LifecycleBase.start()调用父类startInternal方法
StandardHost.startInternal()Host实例化
Host的实例化,是通过设置容器生命周期状态(STARTING)。
通过触发Host生命周期事件fireLifecycleEvent来执行后续工作(实例化Context,交给HostConfig进行,HostConfig是生命周期事件监听器,触发对应事件)。
ContainerBase.startInternal()触发start生命周期事件
LifecycleBase.setStateInternal()循环调用监听器
LifecycleBase.fireLifecycleEvent()监听器进行业务逻辑处理
HostConfig.lifecycleEvent()
HostConfig.lifecycleEvent()调用start方法部署webapp应用
HostConfig.start()deployApps,处理Host下多个应用
HostConfig.deployApps()以多线程的方式处理Host下多个应用(目录模式)
deployDirectories,处理host下以目录方式部署的app-context
app处理的时候也是以多线程方式处理(results.add(es.submit(new DeployDirectory(this, cn, dir)));)
HostConfig.deployDirectories()run方法
HostConfig.DeployDirectory()webapp 部署的具体方法
HostConfig.deployDirectory()host.addChild(centext)时才去触发Context实例核心内容,比如wrapper-serlvet的封装
调用父类addChild方法
StandardHost.addChild()进一步调用
ContainerBase.addChild()处理具体的Context
ContainerBase.addChildInternal()
具体的Context再次向统一生命周期管理类报道
LifecycleBase.start()创建工作目录
StandardContext.startInternal()设置类加载器
StandardContext.startInternal()具体的读取web.xml封装wrapper
Context具体的读取web.xml封装wrapper过程使用事件驱动,交给了ContextConfig(它也是一个事件监听器)
StandardContext.startInternal()加载初始化Servlet
StandardContext.startInternal()
findChildren值(计算表达式)
0,第一访问时加载;1,容器启动时加载;判断是否在启动是加载初始化
StandardContext.loadOnStartup()调用wrapper.load()
StandardContext.loadOnStartup()实例化Servlet
StandardWrapper.load()
StandardWrapper.loadServlet()
findChildren值(计算表达式)连接器启动
info:开始走连接器启动分支了
StandardService.startInternal()向统一生命周期管理类报道
LifecycleBase.start()PortocolHandler启动
Connector.startInternal()EndPoint初始化
AbstractProtocol.start()
AbstractEndPoint.start()NIO模型
NIO模型
NioEndpoint.startInternal()创建Acceptor
NioEndpoint类
NioEndpoint.acceptor()OK,到此Tomcat的启动流程大概走完了,下一篇我们去看看Servlet处理请求的逻辑是什么样的。
