• SpringMvc(零)- Tomcat启动


    前言

    本篇没有营养,只是记录的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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在获取到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.ContextLoaderListenerlistener-class>
        listener>
    
    • 1
    • 2
    • 3

    image-20221010221544536

    image-20221010222145625

    10. 初始化servlet容器

    最后会执行子容器的启动

    image-20221010221655107

    位置:

    org.springframework.web.servlet.FrameworkServlet#initServletBean

    image-20221010221024398

  • 相关阅读:
    【字符串】数组中的字符串匹配
    请求prometheus数据然后使用tensorflow计算正则模型
    汇率查询接口
    特征工程实战篇
    每天 20 题吃透这份将近 500 页的“Java 工程师八股文”,成功入职阿里
    Linux上部署net6应用
    大模型的开源不同于传统的开源软件
    前端研习录(23)——JavaScript数组及其方法合集
    Springboot整合Flowable6.x导出bpmn20
    重庆大自考和小自考的区别是什么?
  • 原文地址:https://blog.csdn.net/qq_28911061/article/details/127332452