转载地址:http://www.tianshouzhi.com/api/tutorials/spring

1、spring和springmvc父子容器概念介绍

在spring和springmvc进行整合的时候,一般情况下我们会使用不同的配置文件来配置spring和springmvc,因此我们的应用中会存在至少2个ApplicationContext实例,由于是在web应用中,因此最终实例化的是ApplicationContext的子接口WebApplicationContext。如下图所示:

上图中显示了2个WebApplicationContext实例,为了进行区分,分别称之为:Servlet WebApplicationContext、Root WebApplicationContext。 其中:

  • Servlet WebApplicationContext:这是对J2EE三层架构中的web层进行配置,如控制器(controller)、视图解析器(view resolvers)等相关的bean。通过spring mvc中提供的DispatchServlet来加载配置,通常情况下,配置文件的名称为spring-servlet.xml。
  • Root WebApplicationContext:这是对J2EE三层架构中的service层、dao层进行配置,如业务bean,数据源(DataSource)等。通常情况下,配置文件的名称为applicationContext.xml。在web应用中,其一般通过ContextLoaderListener来加载。

以下是一个web.xml配置案例:

<?xml version="1.0" encoding="UTF-8"?>  

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <!—创建Root WebApplicationContext-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!—创建Servlet WebApplicationContext-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping> </web-app>

在上面的配置中:

  • 1、ContextLoaderListener会被优先初始化时,其会根据<context-param>元素中contextConfigLocation参数指定的配置文件路径,在这里就是"/WEB-INF/spring/applicationContext.xml”,来创建WebApplicationContext实例。 并调用ServletContext的setAttribute方法,将其设置到ServletContext中,属性的key为”org.springframework.web.context.WebApplicationContext.ROOT”,最后的”ROOT"字样表明这是一个 Root WebApplicationContext。
  • 2、DispatcherServlet在初始化时,会根据<init-param>元素中contextConfigLocation参数指定的配置文件路径,即"/WEB-INF/spring/spring-servlet.xml”,来创建Servlet WebApplicationContext。同时,其会调用ServletContext的getAttribute方法来判断是否存在Root WebApplicationContext。如果存在,则将其设置为自己的parent。这就是父子上下文(父子容器)的概念。

父子容器的作用在于,当我们尝试从child context(即:Servlet WebApplicationContext)中获取一个bean时,如果找不到,则会委派给parent context (即Root WebApplicationContext)来查找。
如果我们没有通过ContextLoaderListener来创建Root WebApplicationContext,那么Servlet WebApplicationContext的parent就是null,也就是没有parent context。

2、为什么要有父子容器

笔者理解,父子容器的作用主要是划分框架边界。
        在J2EE三层架构中,在service层我们一般使用spring框架, 而在web层则有多种选择,如spring mvc、struts等。因此,通常对于web层我们会使用单独的配置文件。例如在上面的案例中,一开始我们使用spring-servlet.xml来配置web层,使用applicationContext.xml来配置service、dao层。如果现在我们想把web层从spring mvc替换成struts,那么只需要将spring-servlet.xml替换成Struts的配置文件struts.xml即可,而applicationContext.xml不需要改变。
        事实上,如果你的项目确定了只使用spring和spring mvc的话,你甚至可以将service 、dao、web层的bean都放到spring-servlet.xml中进行配置,并不是一定要将service、dao层的配置单独放到applicationContext.xml中,然后使用ContextLoaderListener来加载。在这种情况下,就没有了Root WebApplicationContext,只有Servlet WebApplicationContext。

3、相关问题

1.为什么不能在Spring的applicationContext.xml中配置全局扫描

如果都在spring容器中,这时的SpringMVC容器中没有对象,所以加载处理器,适配器的时候就会找不到映射对象,映射关系,因此在页面上就会出现404的错误。
因为在解析@ReqestMapping解析过程中,initHandlerMethods()函数只是对Spring MVC 容器中的bean进行处理的,并没有去查找父容器的bean。因此不会对父容器中含有@RequestMapping注解的函数进行处理,更不会生成相应的handler。所以当请求过来时找不到处理的handler,导致404。

2.如果不用Spring容器,直接把所有层放入SpringMVC容器的配置spring-servlet.xml中可不可以

如果把所有层放入SpringMVC的。但是事务和AOP的相关功能不能使用(事务的时候,是在同一个容器才能达到事务作用,可能是因为sprigmvc容器事务相关没有配置,这个还没有验证)。

3.同时扫描

会在两个父子IOC容器中生成大量的相同bean,这就会造成内存资源的浪费。

一般正常的操作

因为@RequestMapping一般会和@Controller搭配使。为了防止重复注册bean,建议在spring-servlet.xml配置文件中只扫描含有Controller bean的包,其它的共用bean的注册定义到applicationContext.xml文件中。

applicationContext.xml

    <context:component-scan base-package="org.xuan.springmvc">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

spring-servlet.xml

    <context:component-scan base-package="org.xuan.springmvc.controller"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

注意

1.Spring容器导入的properties配置文件,只能在Spring容器中用而在SpringMVC容器中不能读取到。 需要在SpringMVC 的配置文件中重新进行导入properties文件,并且同样在父容器Spring中不能被使用,导入后使用@Value("${key}")在java类中进行读取。

spring与springmvc父子容器的更多相关文章

  1. Spring和springMVC父子容器的关系

    部分转载自:https://www.cnblogs.com/ljdblog/p/7461854.html springMVC容器和Spring容器 为什么一定要在web.xml中配置spring的li ...

  2. (转载)Spring与SpringMVC父子容器的关系与初始化

    转自 https://blog.csdn.net/dhaiuda/article/details/80026354 Spring和SpringMVC的容器具有父子关系,Spring容器为父容器,Spr ...

  3. 1、spring与springmvc父子容器

    转载于http://www.tianshouzhi.com/api/tutorials/spring 1.0 spring与springmvc父子容器 1.spring和springmvc父子容器概念 ...

  4. Spring和SpringMVC父子容器关系初窥

    一.背景 最近由于项目的包扫描出现了问题,在解决问题的过程中,偶然发现了Spring和SpringMVC是有父子容器关系的,而且正是因为这个才往往会出现包扫描的问题,我们在此来分析和理解Spring和 ...

  5. spring和springmvc父子容器关系

    一般来说,我们在整合spring和SpringMVC这两个框架中,web.xml会这样写到: <!-- 加载spring容器 --> <!-- 初始化加载application.xm ...

  6. 面试高频题:说一说对Spring和SpringMvc父子容器的理解?

    引言 以前写了几篇关于SpringBoot的文章<面试高频题:springBoot自动装配的原理你能说出来吗>.<保姆级教程,手把手教你实现一个SpringBoot的starter& ...

  7. Spring和springmvc父子容器注解扫描问题详解

      一.Spring容器和springmvc容器的关系如下图所示: Spring和springmvc和作为两个独立的容器,会把扫描到的注解对象分别放到两个不同的容器中, Springmvc容器是spr ...

  8. 转:spring的启动过程-spring和springMVC父子容器的原理

    要想很好理解这三个上下文的关系,需要先熟悉spring是怎样在web容器中启动起来的.spring的启动过程其实就是其IoC容器的启动过程,对于web程序,IoC容器启动过程即是建立上下文的过程. s ...

  9. Spring与SpringMVC的容器关系分析

    Spring和SpringMVC作为Bean管理容器和MVC层的默认框架,已被众多WEB应用采用,而实际使用时,由于有了强大的注解功能,很多基于XML的配置方式已经被替代,但是在实际项目中,同时配置S ...

随机推荐

  1. ListView与GridView优化

    前言 ListView是Android中最常用的控件,通过适配器来进行数据适配然后显示出来,而其性能是个很值得研究的话题.本文与你一起探讨Google I/O提供的优化Adapter方案,欢迎大家交流 ...

  2. GIT 单个文件还原到历史版本号

    首先检查在历史文件中的版本号信息:git log <file> 将文件还原到历史版本号:git reset 版本号 <file> 文档工作区的检测:git checkout - ...

  3. 开源软件的许可(License)

    自由软件基金会(Free Software Foundation):FSF 0. GNU GNU (GNU is Not Unix 的递归缩写)计划,又称革奴计划,是由 Richard Stallma ...

  4. uwp - 禁用屏幕翻转/禁用屏幕旋转/禁用横屏模式

    原文:uwp - 禁用屏幕翻转/禁用屏幕旋转/禁用横屏模式 解决方案目录 > Package.appxmanifest 双击打开,把支持的旋转:纵向勾上,只勾这一个其他不勾,就可以了.同理,想让 ...

  5. Visual C# 2010 实现资源管理器

    演练:使用设计器创建带有 ListView 和 TreeView 控件的资源管理器样式的界面 Visual Studio 2010     其他版本     此主题尚未评级 - 评价此主题   Vis ...

  6. 开源库(要不要重新制造轮子)—— C/C++、Java、Python

    谷歌近期开源的SLAM方案:Cartographer Boost:准标准的C++库. Eigen3: 准标准的线性代数库. Lua:非常轻量的脚本语言,主要用来做Configuration Ceres ...

  7. WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式

    原文:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式 由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件.这篇文章介绍在WPF中实现PropertyGr ...

  8. WPF特效-实现3D足球效果

    原文:WPF特效-实现3D足球效果 WPF 实现 3D足球效果,效果图如下:  每个面加载不同贴图. <UserControl x:Class="MediaBalll.Model3Ds ...

  9. WPF Layout 系统概述——Measure

    原文:WPF Layout 系统概述--Measure 前言 在WPF/Silverlight当中,如果已经存在的Element无法满足你特殊的需求,你可能想自定义Element,那么就有可能会面临重 ...

  10. 【全面解禁!真正的Expression Blend实战开发技巧】第四章 从最常用ButtonStyle开始 - PathButton

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第四章 从最常用ButtonStyle开始 - PathButton 上一篇我们介绍了TextButton,但为了追求界面的张力, ...