spring源码分析-spring与tomcat整合原理

spring源码分析-spring与tomcat整合原理

spring与tomcat整合的整理的流程图如下:
在这里插入图片描述

流程图解析:

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()方法,如下所示:

/** * ApplicationListener endpoint that receives events from this servlet's WebApplicationContext * only, delegating to {@code onApplicationEvent} on the FrameworkServlet instance. */
private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {
   

   @Override
   public void onApplicationEvent(ContextRefreshedEvent event) {
   
      FrameworkServlet.this.onApplicationEvent(event);
   }
}

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

/** * This implementation calls {@link #initStrategies}. */
@Override
protected void onRefresh(ApplicationContext context) {
   
   initStrategies(context);
}

/** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize further strategy objects. */
protected void initStrategies(ApplicationContext context) {
   
   initMultipartResolver(context);
   initLocaleResolver(context);
   initThemeResolver(context);
   initHandlerMappings(context);
   initHandlerAdapters(context);
   initHandlerExceptionResolvers(context);
   initRequestToViewNameTranslator(context);
   initViewResolvers(context);
   initFlashMapManager(context);
}

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111200.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python读取pkl_Python 读取文件

    python读取pkl_Python 读取文件使用python读取pkl文件内容可能会出现一些错误,下面将介绍一些解决的方法。importcPicklef=open(‘subj0.pkl’)#文件所在路径inf=cPickle.load(f)#读取pkl内容printinff.close()有时候,还是出现错误EOFEORROR,可以通过合并第2,3行,即:inf=cPickle.load(open(‘subj

    2025年10月12日
    2
  • Windows 10配置远程开机[通俗易懂]

    Windows 10配置远程开机[通俗易懂]简介最近有个需求,在外边或者是上班的时候想从家里的电脑拿点资料,虽然家里的路由器有公网IP地址,但是电脑总不能一直开着吧,然后就想到可以远程通过网卡唤醒电脑。前提条件拥有一个公网IP(一般可以找运营商申请),如果拥有的公网IP是动态的话,需要绑定DDNS域名,DDNS域名可以自行注册。 电脑主板支持网络唤醒功能。配置方法主板开启网络唤醒功能,如图:设置网络适配器支持唤醒…

    2022年5月5日
    162
  • javascript–正则表达式

    javascript–正则表达式

    2021年9月12日
    55
  • pycharm 激活码在线[最新免费获取]

    (pycharm 激活码在线)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月28日
    60
  • Docker网络,网络工程师还不赶紧收藏!

    Docker网络,网络工程师还不赶紧收藏!学习Docker网络前建议清空所有环境dockerrmi-f$(dockerimages-aq)每启动一个docker容器,docker就会给docker容器分配一个ip。只要安装了docker,就会有一个网卡docker0(桥接模式,使用的是evth-pair技术)什么是Evth-pairEvth-pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连.正因为这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备。OpenStac,Dock

    2022年7月19日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号