SpringMvc(零)- Tomcat启动SpringMvc

前言

本篇没有营养,只是记录的Tomcat的启动的一个过程,非常粗略,目的是为了了解,Tomcat是怎么加载SpringMvc并启动SpringMvc的,基本上只记录了关键位置,比如创建关键对象、加载配置、及通知应用的方式等等。

后续考虑深入研究下。

Tomcat关键流程

水平有限,简单的对Tomcat启动及应应用的启动做了一个简单的说明,没什么技术含量,单纯的想知道Tomcat是怎么启动应用的。

1. 引导程序

位置: org.apache.catalina.startup.Bootstrap#main

image-20221008231946741

2. 实例化Catalina容器

这里初始化类加载,然后反射调用setParentClassLoader(URLClassloader)

之后command=“start” 表示启动,之后调用load()方法,进行调用Catalina.load() 方法

image-20221008232850814

3. 创建server, service

之后会进入到:org.apache.catalina.startup.Catalina#load()

image-20221008233033425

这里初始化了一些东西,解析并加载了server.xml,

这里的server.xml 解析后是StandardServer(实现Server接口)对象,这里我们将它看做Tomcat容器(并不是web服务容器)

可以查看server.xml,它有几个标签

<server>
	<service>
        <Connector></Connector>
        <Engine></Engine>
        <Host></Host>
        <Realm></Realm>
    </service>
</server>

在获取到server对象后,它随即将Catalina设置进去了,Catalina是servlet容器,

然后在初始了日志输出,

4. 创建Engine,Connector

最后调用getServer().init() 方法,init()是StandardServer的父类LifecycleBase默认实现的,如下:

他会逐步的调用子容器的init

image-20221008234335290

最后在StandardService里engine.init(), connector.init()

image-20221008234530657

走到这里,它创建了Engine对象,和connector对象,此时engine和connector都是StandardServer的属性

5. 启动

位置:org.apache.catalina.core.StandardServer#startInternal

image-20221008235203941

6. 创建StandardContext(Tomcat上下文)

StandardContext 是为也可以看做Tomcat上下文对象,很多操作都有它处理,用于处理请求、加载、初始化等操作,它就提供了获取servlet上下文对象(servletContext)的方法,还可以设置应用监听器、读取web.xml、设置编码等操作。

位置:org.apache.catalina.startup.Bootstrap#main

image-20221010210030658

daemon.load 上面第六步前的过程,它创建容器server -> service (Engine connector)

到这一步,它是反射执行Catalina.start()方法

image-20221010210112362

然后一步步的去调用内部子容器的start()方法

在调用engine.start()

org.apache.catalina.mbeans.MBeanFactory#createStandardContext(java.lang.String, java.lang.String, java.lang.String, boolean, boolean)

7. 解析web.xml并加载

org.apache.catalina.startup.ContextConfig#webConfig

它先是加载了应用的web.xml,然后将Tomcat的web.xml进行merge

然后将web.xml的配置都加到ServletContext中:org.apache.catalina.startup.ContextConfig#configureContext

image-20221010211825762

然后再将调用外部方法通知的类加入到servletContext

image-20221010211947624

8. 调用SpringMvc的应用初始化程序

位置:org.apache.catalina.core.StandardContext#startInternal

然后调用外部通知方法

image-20221010212236192

它这里是entry.getKey().onStartup,它的是org.springframework.web.SpringServletContainerInitializer

然后这里就到了springMvc的org.springframework.web.SpringServletContainerInitializer#onStartup

image-20221010212756321

可是,这里Tomcat给它传了4个抽象类,根据注释这个方法是提供给我们做其他web应用程序初始化的方法,感觉是我们也可以做类似Tomcat的web服务器,将其他web应用进行扫描然后读取到这4个抽象类实现的类进行上下文传递

9. 初始化spring容器

上面执行应用初始化程序,没有进行初始化,但是在这一步,就会走我们在web.xml配置的类ContextLoaderListener,然后初始化spring容器。

监听器在解析web.xml时就已经添加,所以这里只要执行就行

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

image-20221010221544536

image-20221010222145625

10. 初始化servlet容器

最后会执行子容器的启动

image-20221010221655107

位置:

org.springframework.web.servlet.FrameworkServlet#initServletBean

image-20221010221024398

猜你喜欢

转载自blog.csdn.net/qq_28911061/article/details/127332452