Spring MVC 中的 ApplicationContext 和 WebApplicationContext 有啥区别?

Posted

技术标签:

【中文标题】Spring MVC 中的 ApplicationContext 和 WebApplicationContext 有啥区别?【英文标题】:What is the difference between ApplicationContext and WebApplicationContext in Spring MVC?Spring MVC 中的 ApplicationContext 和 WebApplicationContext 有什么区别? 【发布时间】:2012-07-27 09:09:00 【问题描述】:

Application Context 和 Web Application Context 有什么区别?

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

我想知道 ApplicationContext 在 MVC 应用程序中有什么用? ApplicationContext中定义了什么样的bean?

【问题讨论】:

我不相信那是***.com/questions/3652090/… 的副本那个问题询问web.xml 文件的内容;这个问题是在询问一些 Spring 课程。 @Raedwald 这不是真的。另一个问题不是在谈论web.xml,而是在谈论ApplicationContextWebApplicationContext 的Spring XML bean 配置变体。 applicationContext.xml 中的所有 bean 定义都将在 ApplicationContext 中可用,而 *-servlet.xml 中的所有 bean 定义将在 WebApplicationContext 中可用。 【参考方案1】:

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

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

request - 将单个 bean 定义限定为单个 HTTP 请求的生命周期;也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义的后面创建的 session - 将单个 bean 定义限定为 HTTP 会话的生命周期 application - 将单个 bean 定义限定为 ServletContext 的生命周期

【讨论】:

【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

引用自Spring web framework reference

顺便说一句,servlet 和根上下文 都是 webApplicationContext:

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

public interface WebApplicationContext extends ApplicationContext 
    ServletContext getServletContext();

在 WebApplicationContext 中实例化的 Bean 如果实现了 ServletContextAware 接口,也将能够使用 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 应用程序中有两个层次结构级别,根和 servlet 上下文:。

这允许您将一些服务作为整个应用程序的单例运行(Spring Security bean 和基本数据库访问服务通常驻留在此处),另一个作为相应 servlet 中的独立服务运行,以避免 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。

另请参阅:Difference between applicationContext.xml and spring-servlet.xml in Spring Framework

【讨论】:

非常感谢您的回答。我听说有两种类型的上下文也用于 Web 应用程序。一个用作根应用程序上下文,其中提供与 Web 无关的定义示例服务、dao 配置等,另一个用作特定于 Web 的配置,如 Handler Mappings 等。先验用作父上下文,后者用作子上下文.我想知道如何声明这个结构。我听说过一些 ContextListener 回调。但我不太清楚。 这样的结构在Spring servlet工具中是硬编码的,spring web app中总是至少有两个应用上下文,看更新的答案,希望对你有帮助。 优秀的描述..我对这种情况有一些疑问..因为我处于初始阶段,我找到了你有用的答案来获取一些知识.. "如果当前应用程序上下文中不存在所需的 bean,将从父上下文中获取它"。你能解释一下怎么做吗? Web 应用程序上下文如何访问根应用程序上下文中的 bean?链接到任何示例? 嗨@BorisTreukhov,我的理解是:即使我们没有在MVC应用程序中配置“contextConfigLocation”,根ApplicationContext仍然会在没有任何配置集的情况下被实例化/创建。所以我们可以说,一个 Spring Web 应用程序至少默认实例化了两个上下文:一个 WebApplicationContext 和一个 Root ApplicationContext。如果我错了,请纠正我。谢谢!

以上是关于Spring MVC 中的 ApplicationContext 和 WebApplicationContext 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

spring boot mvc - 不支持内容类型'application/json;charset = UTF-8'

Spring MVC 和 Application Context 多次刷新尝试

Spring Boot 和 MVC:如何从 application.properties 为 @RequestBody 对象字段设置默认值?

在我的(java spring mvc + mysql application,thymeleaf)中实现spring security之后,身份验证发生了一些奇怪的事情

Spring MVC + Ajax 错误 400

Spring MVC + JSON = 406 不可接受