Spring与SpringMVC父子容器问题

父子容器关系

在Spring整体框架的核心概念中,容器是核心思想,就是用来管理Bean的整个生命周期的,而在一个项目中,容器不一定只有一个,Spring中可以包括多个容器,而且容器有上下层关系,目前最常见的一种场景就是在一个项目中引入Spring和SpringMVC这两个框架,那么它其实就是两个容器,Spring是父容器,SpringMVC是其子容器,并且在Spring父容器中注册的Bean对于SpringMVC容器中是可见的,而在SpringMVC容器中注册的Bean对于Spring父容器中是不可见的,也就是子容器可以看见父容器中的注册的Bean,反之就不行。

看一眼web.xml的配置

    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>dmsd.itoo</param-value>
    </context-param>
    <context-param>
       <!-- 加载Spring容器,指定spring ioc配置文件的位置 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/spring.xml</param-value>
    </context-param>
    	<!--<listener>-->
		<!--<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>-->
	<!--</listener>-->
    
    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <!-- 初始化参数,配置springmvc配置文件 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>            
            <param-value>classpath:spring/spring-mvc.xml</param-value>
        </init-param>
            <!-- 启动级别为1,则web容器启动时就加载该Servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

Spring IOC初始化过程

1、web应用程序启动时,tomcat会读取web.xml文件中的context-parm(含有配置文件的路径)和listener节点,接着会为应用程序创建一个ServletContext,为全局共享,Spring ioc容器就是存储在这里
2、tomcat将context-param节点转换为键值对,写入到ServletContext中
3、创建listener节点中的ContextLoaderListener实例,调用该实例,初始化webapplicationContext,这是一个接口,其实现类为XmlWebApplicationContext(即spring的IOC容器),其通过ServletContext.getinitialParameter(“contextConfigLoaction”)从ServletContext中获取context-param中的值(即spring ioc容器配置文件的路径),这就是为什么要有第二步的原因。接着根据配置文件的路径加载配置文件信息(其中含有Bean的配置信息)到WebApplicationContext(即spring ioc容器)中,将WebApplicationContext以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取。至此,spring ioc容器初始化完毕
4、容器初始化web.xml中配置的servlet,为其初始化自己的上下文信息servletContext,并加载其设置的配置信息到该上下文中。将WebApplicationContext(即spring ioc容器)设置为它的父容器。其中便有SpringMVC(假设配置了SpringMVC),这就是为什么spring ioc是springmvc ioc的父容器的原因

springMVC的初始化过程

SpringMVC主要是servlet标签下配置的DispatcherServlet(前端控制器)来完成自身的初始化
在这里插入图片描述
每个servlet在初始化时候都会先调用默认构造函数然后调用init函数,而DispatcherServlet的init方法在其父类HttpServlet中;
在HttpServlet的init函数中,完成了对web.xml文件中与DispatcherServlet有关参数的读取,初始化了DispatcherServlet;
往下,其子类FrameworkServlet中,完成了对SpringMVC IOC容器的的创建,并且将Spring IOC容器设定为Spring MVC 的子容器,将Spring MVC IOC容器注册到了servlet Context中;
最后:DispatcherServlet完成对策略组件的初始化;
spring MVC 容器初始化完毕

总结:

  • 先加载父容器(spring),后加载子容器(springmvc)。所以在Controller里面注入service时,父容器中的bean已经初始化完毕。
  • 在父子容器中,父容器元素对子容器可见,子容器对父容器的元素不可见。所以父容器中不能获取子容器的元素,但是子容器可以获取父容器的元素。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页