Tomcat的启动过程

文章中所有->代表调用

1. 寻找启动入口

(1)可以观察启动脚本

bin/startup.sh -> bin/catalina.sh -> org.apache.catalina.startup.Bootstrap start

(2)或者观察进程启动命令

ps -ef|grep tomcat ->  org.apache.catalina.startup.Bootstrap start

可以看出tomcat的入口是Bootstrap类,传入start参数。

2. 观察Bootstrap类

Bootstrap类为tomcat的启动辅助类。

main() -> init()    
       -> start()

(1)init方法会初始化org.apache.catalina.startup.Catalina的实例
(2)start方法会调用Catalina的start方法

3. 观察Catalina类

Catalina是一个servlet容器,Catalina中包含一个Server。

start() -> load() -> createStartDigester()
                  -> digester.push(this)
                  -> digester.parse()
                  -> getServer().init()
        -> getServer().start()

(1)createStartDigester方法中会定义如何将server.xml转化为一个个对象,并如何组装起来

digester.addObjectCreate("Server","org.apache.catalina.core.StandardServer","className");
digester.addSetProperties("Server");
digester.addSetNext("Server","setServer","org.apache.catalina.Server");

如上,会读取Server节点的元素为StandardServer对象,并使用setServer方法设置进去

digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));

如上,需要跟踪HostRuleSet的addRuleInstances方法,可发现会使用addChild方法设置Host到Engine里

(2)digester将this传入,并调用parse方法,则将server.xml中的对象组装好,并将根元素Server通过setServer设置到Catalina里

(3)初始化Server,tomcat的各个组件都是继承LifeCycleBase类,组件间自行编写initInternal方法,将一层一层的初始化好所有组件。

(4)启动Server,同理,tomcat的各个组件自行编写startInternal方法,一层一层的启动所有组件。

4. 观察StandardServer类

startInternal() -> globalNamingResources.start()
                -> services[i].start()

(1)主要是启动Server下的若干个Service。

5. 观察StandardService类

startInternal() -> engine.start()
                -> executor.start()
                -> connector.start()

(1)Service启动engine/executor/connecor

6. 观察StandardEngine类

startInternal() -> super.startInternal() -> threadStart()

(1)在StandardEngine的startInternal方法中并没有看到启动它的下级组件Host,其实在组装StandardEngine时已经启动好Host了,可以观察addChild方法。

addChild() -> super.addChild() -> addChildInternal() -> child.start()

对于Host下的Context也是同理。
(2)threadStart方法中启动了一个后台线程用来处理connector接受的请求,名为ContainerBackgroundProcessor[StandardEngine[Catalina]]

7. 观察Connector类

startInternal() -> protocolHandler.start() -> endpoint.start() -> startAcceptorThreads()

(1)一个Connector对应一个协议,启动Connector时会启动该协议的handler,启动时会启动线程组用来监听端口接收请求

猜你喜欢

转载自blog.csdn.net/lblblblblzdx/article/details/80946288