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