Spring MVC中的ApplicationContext和WebApplicationContext有什么区别?


193

应用程序上下文和Web应用程序上下文之间有什么区别?

我知道WebApplicationContext用于Spring MVC架构的应用程序吗?

我想知道ApplicationContextMVC应用程序中有什么用途?以及定义了ApplicationContext哪种豆类?


5
我不认为这是stackoverflow.com/questions/3652090/的重复。。。这个问题询问web.xml文件的内容。这个问题问的是一些Spring课程。
Raedwald 2013年

@Raedwald并非如此。另一个问题不是在谈论web.xml而是在谈论ApplicationContextand 的Spring XML bean配置变量WebApplicationContext。中的所有bean定义applicationContext.xml将在中提供,ApplicationContext而中的所有bean定义*-servlet.xml将在中提供WebApplicationContext
g00glen00b

Answers:


227

Web应用程序上下文扩展了应用程序上下文,该上下文旨在与标准javax.servlet.ServletContext一起使用,因此能够与容器进行通信。

public interface WebApplicationContext extends ApplicationContext {
    ServletContext getServletContext();
}

如果WebBean中实现ServletContextAware接口,则在WebApplicationContext中实例化的Bean也将能够使用ServletContext。

package org.springframework.web.context;
public interface ServletContextAware extends Aware { 
     void setServletContext(ServletContext servletContext);
}

ServletContext实例可以做很多事情,例如,通过调用getResourceAsStream()方法访问WEB-INF资源(xml配置等)。通常,在Servlet Spring应用程序的web.xml中定义的所有应用程序上下文都是Web应用程序上下文,这既适用于根Webapp上下文,也适用于Servlet的应用程序上下文。

另外,取决于Web应用程序上下文的功能,可能会使您的应用程序更难测试,并且可能需要使用MockServletContext类进行测试。

servlet和根上下文的区别 Spring允许您构建多级应用程序上下文层次结构,因此,如果当前应用程序上下文中不存在所需的bean,则将从父上下文中获取所需的bean。在Web应用程序中,默认情况下有两个层次结构级别,即root和servlet上下文:Servlet和根上下文

这使您可以将某些服务作为整个应用程序的单例运行(Spring Security Bean和基本数据库访问服务通常位于此处),而另一项则作为相应服务中的单独服务运行,以避免Bean之间发生名称冲突。例如,一个Servlet上下文将为网页提供服务,而另一个将实现无状态Web服务。

当使用spring servlet类时,这两个级别的分离是开箱即用的:要配置根应用程序上下文,应在web.xml中使用context-param标记。

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

(根应用程序上下文是由ContextLoaderListener创建的,它在web.xml中声明

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

)和Servlet应用程序上下文的servlet标签

<servlet>
   <servlet-name>myservlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>app-servlet.xml</param-value>
   </init-param>
</servlet>

请注意,如果省略init-param,那么在此示例中spring将使用myservlet-servlet.xml。

另请参阅:Spring Framework中applicationContext.xml和spring-servlet.xml之间的区别


2
非常感谢您的回答。我听说有两种类型的上下文也用于Web应用程序。一个用作根应用程序上下文,其中提供了与Web无关的定义,例如服务,Dao配置等,另一个用作特定于Web的配置(例如Handler Mappings等)。前者用作父上下文,后者用作子上下文。 。我想知道如何声明此结构。我听说过一些ContextListener回调。但是我还不清楚。
Sumit Trehan

1
这种结构在Spring servlet工具中进行了硬编码,spring web应用程序中始终至少有两个应用程序上下文,请参见更新后的答案,希望对您有所帮助。
鲍里斯·特鲁霍夫

优秀的说明。.我对此方案有疑问。.
由于

“如果当前应用程序上下文中不存在必需的Bean,将从父上下文中获取它”。你能解释一下吗?Web应用程序上下文如何在根应用程序上下文中访问bean?链接到任何示例?
anir

14

回到Servlet时代,web.xml只能有一个<context-param>,因此当服务器加载应用程序时,只有一个上下文对象被创建,并且该上下文中的数据在所有资源之间共享(例如:Servlet和JSP)。它与在上下文中具有数据库驱动程序名称相同,但不会更改。以类似的方式,当我们在<contex-param>Spring中声明contextConfigLocation参数时,将创建一个Application Context对象。

 <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.myApp.ApplicationContext</param-value>
 </context-param>

一个应用程序中可以有多个Servlet。例如,您可能想以一种方式处理/ secure / *请求,并以另一种方式处理/ non-seucre / *。对于每个这些Servlet,您都可以有一个上下文对象,它是WebApplicationContext。

<servlet>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.secure.SecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>SecureSpringDispatcher</servlet-name>
    <url-pattern>/secure/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.myapp.non-secure.NonSecureContext</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>NonSecureSpringDispatcher</servlet-name>
    <url-pattern>/non-secure/*</url-patten>
</servlet-mapping>

13

可接受的答案是通过的,但对此有官方解释:

WebApplicationContext是纯ApplicationContext的扩展,具有Web应用程序必需的一些额外功能。它与常规ApplicationContext的不同之处在于,它能够解析主题(请参阅使用主题),并且知道它与哪个Servlet关联(通过链接到ServletContext)。WebApplicationContext绑定在ServletContext中,并且通过在RequestContextUtils类上使用静态方法,如果需要访问WebApplicationContext,则始终可以查找它。

Spring Web Framework参考引用

顺便说servlet和根上下文有两个 web应用上下文:

Spring Web MVC中的典型上下文层次结构


6

ApplicationContext(根应用程序上下文):每个Spring MVC Web应用程序都有一个applicationContext.xml文件,该文件配置为上下文配置的根。Spring加载此文件并为整个应用程序创建一个applicationContext。该文件由ContextLoaderListener加载,该文件在web.xml文件中配置为上下文参数。每个Web应用程序只有一个applicationContext。

WebApplicationContext:WebApplicationContext是可感知Web的应用程序上下文,即它具有servlet上下文信息。一个Web应用程序可以具有多个WebApplicationContext,并且每个Dispatcher Servlet(这是Spring MVC体系结构的前端控制器)都与一个WebApplicationContext相关联。webApplicationContext配置文件* -servlet.xml特定于DispatcherServlet。而且,由于一个Web应用程序可以配置多个服务程序servlet来服务多个请求,因此每个Web应用程序可以有多个webApplicationContext文件。


3

WebApplicationContext接口指定的Web应用程序上下文是Web应用程序的Spring应用程序上下文。只要WebApplicationContext接口扩展了ApplicationContext接口,它就具有常规Spring应用程序上下文的所有属性,并添加了一种用于检索ServletContextWeb应用程序的标准Servlet API的方法。

除了标准的Spring bean范围singletonprototype之外,Web应用程序上下文中还有三个可用范围:

  • request-将单个bean定义的范围限定为单个HTTP请求的生命周期;也就是说,每个HTTP请求都有一个在单个bean定义后面创建的bean实例。
  • session -将单个bean定义的范围限定为HTTP会话的生命周期
  • application -将单个bean定义的范围限定为a的生命周期 ServletContext
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.