`
m635674608
  • 浏览: 5041548 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Spring中DispacherServlet、WebApplicationContext、ServletContext的关系

 
阅读更多

解释一:

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

spring的启动过程:

  1. 首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;

  2. 其次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取;

  3. 再次,contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有spring mvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是mlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。

解释二:

    在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。

Spring API中的解释:

public interface WebApplicationContext
extends ApplicationContext

Interface to provide configuration for a web application. This is read-only while the application is running, but may be reloaded if the implementation supports this.

This interface adds a getServletContext() method to the generic ApplicationContext interface, and defines a well-known application attribute name that the root context must be bound to in the bootstrap process.

Like generic application contexts, web application contexts are hierarchical. There is a single root context per application, while each servlet in the application (including a dispatcher servlet in the MVC framework) has its own child context.

In addition to standard application context lifecycle capabilities, WebApplicationContext implementations need to detect ServletContextAware beans and invoke the setServletContext method accordingly.

http://www.cnblogs.com/snake-hand/p/3161372.html

分享到:
评论

相关推荐

    Spring获取webapplicationcontext,applicationcontext几种方法详解

    此外,由于 Spring 是注入的对象放在 ServletContext 中的,所以可以直接在 ServletContext 中取出 WebApplicationContext 对象: `WebApplicationContext webApplicationContext = (WebApplicationContext) ...

    在web容器(WebApplicationContext)中获取spring中的bean

    Spring把Bean放在这个容器中,普通的类在需要的时候,直接用getBean()方法取出

    Spring MVC之WebApplicationContext_动力节点Java学院整理

    Spring MVC是Java领域非常流行的Web框架,而WebApplicationContext是Spring MVC中用于Web应用的一种特殊的ApplicationContext。在了解WebApplicationContext之前,我们先简单回顾一下Spring的IoC容器。IoC...

    Spring如何获取Bean

    这是因为 Spring 会将 WebApplicationContext 存储在 ServletContext 中。 例如,我们可以使用以下代码来获取 WebApplicationContext。 ```java ServletContext sc = this.getServletContext(); ...

    Spring Web MVC外文翻译

    通过使用 Spring 的 IoC 容器,Spring Web MVC 可以高效地管理 Web 应用程序中的依赖关系,使得整个开发过程更加简洁和高效。 了解 Spring Web MVC 的核心概念和架构设计,对于理解和开发基于 Spring 的 Web 应用...

    Spring2.5中文手册

    - Spring WebApplicationContext扩展了普通的ApplicationContext,为Web应用提供了特定的功能,如处理请求参数、session和ServletContext访问等。 这个`Spring2.5中文手册`包含了上述所有概念的详细解释和示例,...

    在Servlet直接获取Spring框架中的Bean.docx

    在Web应用中,Spring通常会创建一个WebApplicationContext,它与Servlet上下文(ServletContext)关联。 **方法一:使用WebApplicationContextUtils** 在Servlet中,我们可以利用`WebApplicationContextUtils`工具...

    获取spring容器的方法

    在Web环境中,Spring提供了更便捷的方式来获取`ApplicationContext`,即通过`ServletContext`。这尤其适用于Spring MVC或Spring Boot这样的Web应用。可以通过以下方式获取: ```java import org.springframework....

    spring中的所有配置

    ### Spring中的配置详解 #### 1. **监听器(Listener):ContextLoaderListener** 在Spring框架中,`ContextLoaderListener`是一个非常重要的监听器,它用于初始化Web应用程序上下文。当Web容器启动时,它会触发`...

    spring jar 包详解

    - **功能简介**:包含了 Web 应用开发时使用 Spring 框架时所需的核心类,包括自动载入 WebApplicationContext 特性的类、Struts 与 JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。 - **应用场景**:...

    在Eclipse 中创建Spring的 Web应用.doc

    `WebApplicationContext`是Spring在Web环境中管理bean的上下文,而`ServletContext`是Java Web应用的核心对象,它提供了一个全局的数据共享和通信平台。`WebApplicationContext`可以通过`ServletContext`获取,反之...

    spring在web.xml中和在struts中的不同配置.[收集].pdf

    ServletContext也是容器,存储了Web应用的各种属性,包括Spring的WebApplicationContext,这样其他Servlet和Filter就能通过ServletContext获取到ApplicationContext,进而访问和操作Bean。 在Struts中,Spring的...

    spring-web-2.5.jar

    org.springframework.web.context.support.ServletContextResource.class org.springframework.web.context.support.ServletContextResourceLoader.class org.springframework.web.context.support....

    SpringTest_springtest_spring_java_Framework_

    Spring Boot Test则为Spring Boot应用提供了更便捷的测试工具,包括对MockMVC、WebApplicationContext和嵌入式Servlet容器的支持。 "spring"和"java Framework"明确了讨论的焦点是基于Java的Spring框架。Spring框架...

    Spring中ApplicationContext加载机制

    Spring中ApplicationContext加载机制 ApplicationContext 是 Spring 框架中的核心组件之一,负责加载和管理应用程序中的 Bean 对象。在 Web 应用程序中,ApplicationContext 的加载机制是非常重要的, Spring 提供...

    spring 所有功能详解

    **核心容器**提供了Spring框架的基础功能,通过Bean的方式组织和管理Java应用中的各种组件及其之间的关系。在Spring框架中,Bean Factory扮演着核心角色,它实现了工厂模式,用于创建和管理Bean。Bean Factory采用...

    spring-framework 5 中文 参考手册 中文文档

    在Spring中,IoC容器负责创建对象,通过配置元数据来管理对象之间的依赖关系。对象无需自行创建或管理它们的依赖关系,而是通过构造器参数、工厂方法参数或者属性的方式,由IoC容器在创建对象的时候进行注入。这样做...

    spring在web.xml中和在struts中的不同配置..pdf

    在Spring中,Bean的实例化、管理和依赖注入都在这个容器中完成。 在`web.xml`中配置Spring,主要涉及两步。第一步是定义`context-param`,指定Spring的配置文件路径,例如: ```xml &lt;param-name&gt;...

    spring源代码解析

    简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理...

    spring的mvc.doc

    `WebApplicationContext`整合了`ServletContext`的功能,它从`ConcurrentHashMap`中获取`ServletContext`对象,并存储初始化参数。然后,将上下文发布为servlet上下文属性,使得在整个应用中可以通过`...

Global site tag (gtag.js) - Google Analytics