spring与springmvc父子容器

时间:2019-06-18 00:15:27   收藏:0   阅读:129

转载地址: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。 其中:

 以下是一个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>

在上面的配置中:

        父子容器的作用在于,当我们尝试从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的相关功能不能使用。

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类中进行读取。

 

原文:https://www.cnblogs.com/grasp/p/11042580.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!