跟踪源码查看Tomcat启动流程

Tomcat启动流程

一般启动Tomcat会是运行startup.bat或者startup.sh文件,实际上这两个文件最后会调用org.apache.catalina.startup.Bootstrap类的main方法, 那么我们要跟踪源码的话首先要找到源码中的BootStrap类的main方法,然后一步一步追踪源码。
在跟踪源码前我们先来了解一下Bootstrap类的main方法,它主要做了两件事情:
(1)、:定义和初始化了tomcat自己的类加载器,
(2)、:通过反射创建出的一个Catalina对象

现在我们来对照一下源码看看吧!

1、首先在main方法中设置断点
在这里插入图片描述
2、进入bootstrap.init()方法,这个init的方法的作用主要是,初始化对应的类加载器;通过反射创建一个Catalina对象并赋值给 Bootstrap类的属性catalinaDaemon。
在这里插入图片描述

3、bootstrap.init()方法执行完之后意味着bootstrap对象初始化完成,可以将其赋值给Bootstrap类的属性daemon了

在这里插入图片描述
4、然后继续看后面的Bootstrap的main方法后面的代码,发现damon调用它的load方法,那么我们来到这个load的方法体中,发现 Catalina的对象catalinaDaemon被用反射的方式调用它的load方法,

在这里插入图片描述
我们来到Catalina类的load方法,发现真正执行的是其无参的重载方法
在这里插入图片描述
在该无参重载load方法中,首先是创建了一个Digester对象去解析tomcat的xml文件,即server.xml。createStartDigester方法体中主要就是具体的解析server.xml文件的过程。

在这里插入图片描述
接下来还是在该无参重载load方法的后面的代码中找到如下代码

在这里插入图片描述
然后我们点击该server的init方法进入其方法体查看,发现其跳转到了一个Lifecycle接口中去了

在这里插入图片描述
我们知道,Lifecycle是管理tomcat中众多组件的有关生命周期的方法的接口,点击该接口方法旁边的小符号会出现一个实现类的init方法
在这里插入图片描述
点进去之后就会来到了LifecycleBase的init方法,发现其内部又调了一个initInternal方法
在这里插入图片描述
又进入其内部发现其是一个抽象方法,那server的init方法最终调用的是谁的方法呢?(其实这里用到了模板设计模式)

在这里插入图片描述
又点击该小绿色的 I 图标,就会发现其中的实现类了,也就是说,server的init方法最终调用的是对应的server接口的实现类的init方法
在这里插入图片描述

点进去我们就来到了StandardServer类的initInternal方法

在这里插入图片描述
在该initInternal方法的最后,又用for循环去调用了每一个services的init方法进行初始化。

在这里插入图片描述

故接下来我们点击进入services的init方法,发现其又是进入到了Lifecycle接口的方法中,像上面的server.init一样的进入方式,只不过services接口的实现类是StandardServices

在这里插入图片描述
我们进入StandardServices的init方法之后,发现其内部先是调用了engine.init()方法,然后调用executor.init()方法,再调用connector.init()方法。
在这里插入图片描述
由于engine.init()方法里面是一级一级的依次将Host、Context初始化;executor.init()方法也是初始化一个executor,这里就不再查看,感兴趣的可以自己去看看。
现在我们来进入connector.init()方法看看。由于connector也用到了模板设计模式,所以可以通过同样的方式进入其init方法,但其本身就是一个类而不是接口。

​ 在connector的initInternal方法中首先构造了一个CoyoteAdapter对象

在这里插入图片描述
然后在该方法体的下面,其又去调用了protocolHandler.init()方法进行初始化。

在这里插入图片描述
我们进入该protocolHandler.init()方法,由于我们使用的是HTTP1.1版本,故我们选择第一个实现类

在这里插入图片描述
进入其父类的init方法

在这里插入图片描述
发现在其父类的init方法的最后,又去调用了endpoint.init()方法进行初始化

在这里插入图片描述
进入该endpoint.init()初始化方法,我们可以看见其调用了一个bind方法

在这里插入图片描述
该bind方法也是用到了模板设计模式,进入该方法体跟上面的差不多。tomcat8.5及以上其实现类是选择最后那个
在这里插入图片描述
在这里插入图片描述
在bind方法中,我们可以看见与endpoint组件功能相关的socket进行端口监听

以上就是tomcat组件中初始化的大概情况,现在我们回到Bootstrap类的main方法。刚才的一系列初始化是调用了daemon的load方法,现在我们来看看daemon的start方法

在这里插入图片描述
进入该方法

在这里插入图片描述
然后我们去catalina类中找到start方法

在这里插入图片描述
然后相继去调用各个组件的start方法,大致的套路跟分析初始化的情况差不多。

至此我们的启动流程源码跟踪分析差不多就没了~~~

猜你喜欢

转载自blog.csdn.net/glass__sky/article/details/121014767
今日推荐