Spring: DispacherServlet和ContextLoaderListener中的WebApplicationContext的关系

在Web容器(比如Tomcat)中配置Spring时,你可能已经司空见惯于web.xml文件中的以下配置代码:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

以上配置首先会在ContextLoaderListener中通过<context-param>中的applicationContext.xml创建一个ApplicationContext,再将这个ApplicationContext塞到ServletContext里面,通过ServletContext的setAttribute方法达到此目的,在ContextLoaderListener的源代码中,我们可以看到这样的代码:

servletContext.setAttribute(
              WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
 this.context);

以上由ContextLoaderListener创建的ApplicationContext是共享于整个Web应用程序的,而你可能早已经知道,DispatcherServlet会维持一个自己的ApplicationContext,默认会读取/WEB-INFO/<dispatcherServletName>-servlet.xml文件,而我么也可以重新配置:

<servlet>
    <servlet-name>
       customConfiguredDispacherServlet
   </servlet-name>
   <servlet-class>
       org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
       <param-name>
           contextConfigLocation
       </param-name>
       <param-value>
           /WEB-INF/dispacherServletContext.xml
       </param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
</servlet>

问题是:以上两个ApplicationContext的关系是什么,它们的作用作用范围分别是什么,它们的用途分别是什么?

ContextLoaderListener中创建ApplicationContext主要用于整个Web应用程序需要共享的一些组件,比如DAO,数据库的ConnectionFactory等。而由DispatcherServlet创建的ApplicationContext主要用于和该Servlet相关的一些组件,比如Controller、ViewResovler等。

对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext,而反过来不行。

在Spring的具体实现上,这两个ApplicationContext都是通过ServletContext的setAttribute方法放到ServletContext中的。但是,ContextLoaderListener会先于DispatcherServlet创建ApplicationContext,DispatcherServlet在创建ApplicationContext时会先找到由ContextLoaderListener所创建的ApplicationContext,再将后者的ApplicationContext作为参数传给DispatcherServlet的ApplicationContext的setParent()方法,在Spring源代码中,你可以在FrameServlet.java中找到如下代码:

wac.setParent(parent);

其中,wac即为由DisptcherServlet创建的ApplicationContext,而parent则为有ContextLoaderListener创建的ApplicationContext。此后,框架又会调用ServletContext的setAttribute()方法将wac加入到ServletContext中。

当Spring在执行ApplicationContext的getBean时,如果在自己context中找不到对应的bean,则会在父ApplicationContext中去找。这也解释了为什么我们可以在DispatcherServlet中获取到由ContextLoaderListener对应的ApplicationContext中的bean。

时间: 2024-12-17 20:01:32

Spring: DispacherServlet和ContextLoaderListener中的WebApplicationContext的关系的相关文章

Spring ContextLoaderListener 中WebApplicationContext初始化

在spring和structs2整合中,在web.xml文件中需要设置一个listener,如下    <listener>         <listener-class>             org.springframework.web.context.ContextLoaderListener         </listener-class>     </listener> ContextLoaderListener会在web容器初始化的时候进

【Spring】Spring在JavaWeb工程中整合log4j

在<[Spring]Spring3.0.5的下载.配置与Helloworld>(点击打开链接)一文各位已经可能看到了.如果Spring不整合log4j直接启动,则会出现如下关于Spring整合log4j的警告.这个挺烦人的,一方面自己提倡高内聚,低耦合,另一方面,自己没有整合log4j就提出警告.我们程序猿写出来的程序就叫做"耦合",它Spring就叫做"整合".好吧!你只能同时搞明白,log4j是个什么鬼东西,Spring怎么整合log4j,两个问题:

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释

SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释 2016-04-14 23:40 13030人阅读 评论(2) 收藏 举报 分类: SSM(7) 这几天一直在整合SSM框架,虽然网上有很多已经整合好的,但是对于里面的配置文件并没有进行过多的说明,很多人知其然不知其所以然,经过几天的搜索和整理,今天总算对其中的XML配置文件有了一定的了解,所以拿出来一起分享一下,希望有不足的地方大家批评指正~~~ 首先   这篇文章暂时只对框架中所要用到的配置文件进行解

从基础知识到重写Spring的Bean工厂中学习java的工厂模式

1.静态工厂模式其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象这样,就可以控制类的产生过程.顺带提一下单例模式和多例模式:  单例模式是指控制其他对象获得该对象永远只有同一个对象  而多例模式则是根据需要从某个具体集合中获取所需的对象 1 import java.util.ArrayList; 2 import java.util.List; 3 4 5 public class Car implements Moveable{ 6 private

spring在xml文件中配置bean的三种方法

一.最常见,也是缺省,是调用spring的缺省工厂类 spring缺省工厂类:org.springframework.beans.factory.support.DefaultListableBeanFactory使用其静态方法preInstantiateSingletons() 配置文件中最普通最基本的定义一个普通bean<bean id="DvdTypeDAOBean" class="com.machome.dvd.impl.DvdTypeDAO" >

spring整合velocity 配置文件中的属性

spring整合velocity 配置文件中的相关属性 1 <bean id= "viewResolver" class= "org.springframework.web.servlet.view.velocity.VelocityViewResolver" > 2 <!-- 是否缓存模板 --> 3 <property name ="cache" value="false" /> 4 5

Spring Batch在大型企业中的最佳实践

在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是"批处理". 批处理应用通常有以下特点: 数据量大,从数万到数百万甚至上亿不等: 整个过程全部自动化,并预留一定接口进行自定义配置: 这样的应用通常是周期性运行,比如按日.周.月运行: 对数据处理的准确性要求高,并且需要容错机制.回滚机制.完善的日志监控等. 什么是Spring batch Sprin

spring在SSH框架中的作用

从网上了搜了下sring 在ssh中起的作用,在百度知道上看到下面的回答,觉得简单移动,记录下来备查,原文地址: http://zhidao.baidu.com/link?url=JiONrax-Flkpi5hqs_g1HQOrMm1Dk8U1WT88l5T0Gg01bm3M8fMcjUCpqastVxQTd63gxUl5NLyHUQPdq6E-OK 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行

Hibernate+Spring+Struts2整合开发中的一个分页显示方案(转载)

分页显示一直是web开发中一大烦琐的难题,传统的网页设计只在一个JSP或者ASP页面中书写所有关于数据库操作的代码,那样做分页可能简单一点,但当把网站分层开发后,分页就比较困难了,下面是我做Spring+Hibernate+Struts2项目时设计的分页代码,与大家分享交流. 1.DAO层接口的设计,在MemberDao接口中定义了如下两个方法: public interface MemberDao{        //省略了其他的代码        /**     * 分页查询     * @