spring与tomcat整合的整理的流程图如下:

    image.png
    流程图解析:
    1.SPI机制:tomcat启动时会通过SPI的机制加载所有包下面的META-INF/services/javax.servlet.ServletContainerInitializer,读取里面的内容(里面是一个实现了ServletContainerInitializer的类全路径)。此时tomcat就会实例化该全路径的类,然后调用onStartup()这就是spring和tomcat整合的入口,这种spi机制使用的非常广泛,比如springboot原理、数据库驱动等

    2.onStartup方法是读取类上的@HandlerTypes里面的接口的所有实现类,然后调用实现类的onStartup方法

    3.创建父容器:创建父容器是在流程3中创建,此时仅仅是创建,并没有调用核心方法,调用核心方法的时机是后面触发监听器,调用监听器ContextLoadListener的contextInitialized()即流程9

    4.创建子容器:父容器创建之后,就开始创建子容器对应流程6,此时也仅仅是创建而已,并没有调用核心方法refresh,真正的调用刷新方法是在dispatcherservlet调用init方法内,即流程13

    什么是父容器和子容器

    父容器:即springcontext,一般是用来创建和维护公共的一些bean,比如dao等

    子容器:mvccontext,一般用来创建和维护web相关的bean,比如controller

    为什么需要设计父子容器:一般是为了规范,如果你区分项目也是能正常运行的

    5.父容器刷新:spring中ContextLoaderListener监听器实现了servlet的ServletContextListener,servlet初始化会调用监听器contextInitialized方法,所以会调用到ContextLoaderListener.contextInitialized()

    6.子容器刷新:servlet规范中,当一个servlet创建后会调用其init()方法,因此会调用DispathcerServlet.init(),其实现逻辑在父类HttpServletBean中,子容器刷新就是在该方法中实现

    7.事件监听机制:上述父子容器刷新会调用onRefresh()这个就是spring的核心方法了,相信大家都比较熟悉,完成了所有的bean的实例化,并且放入到IOC容器中。在onRefresh()中会将拿到所有ApplicationListener的实现类,并且当spring容器初始化完成后,会调用其onApplicationEvent()方法,其实就是监听者设计模式。然而在FrameworkServlet中就有个内部类ContextRefreshListener实现了ApplicationListener,因此会调用onApplicationEvent()方法,如下所示:

    1. private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
    2. @Override
    3. public void onApplicationEvent(ContextRefreshedEvent event) {
    4. FrameworkServlet.this.onApplicationEvent(event);
    5. }
    6. }

    然后就会调用到如下的方法

    1. /**
    2. * This implementation calls {@link #initStrategies}.
    3. */
    4. @Override
    5. protected void onRefresh(ApplicationContext context) {
    6. initStrategies(context);
    7. }
    8. /**
    9. * Initialize the strategy objects that this servlet uses.
    10. * <p>May be overridden in subclasses in order to initialize further strategy objects.
    11. */
    12. protected void initStrategies(ApplicationContext context) {
    13. initMultipartResolver(context);
    14. initLocaleResolver(context);
    15. initThemeResolver(context);
    16. initHandlerMappings(context);
    17. initHandlerAdapters(context);
    18. initHandlerExceptionResolvers(context);
    19. initRequestToViewNameTranslator(context);
    20. initViewResolvers(context);
    21. initFlashMapManager(context);
    22. }

    到这里需要初始化web的一些资源了,下面就不再继续跟了,感兴趣的可以继续了解。本文是大概梳理了一下spring与tomcat结合的流程,希望对大家有帮助。

    我要在这个基础上继续深入研究

    原文:https://blog.csdn.net/hongtaolong/article/details/107608519