Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数

2024-04-24

我正在阅读 Spring MVC 的文档,并且有一个关于 init 参数的问题。如果有必要的话,我正在使用 Spring 3.2。 contextConfigLocation 和命名空间有什么区别? contextConfigLocation 是否仅用于指定上下文类可以在其中找到 XML 定义的文件夹,而命名空间属性是否用于指定文件名?

<servlet>
        <servlet-name>AppServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF</param-value>
        </init-param>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>application-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

它是否正确?它应该使用/WEB-INF/application-context.xml吗?您应该指定路径吗?


TL;DR

只需设置值contextConfigLocation每当您需要指定自定义配置文件时。这样您就可以指定配置文件名及其位置。

The namespace本质上是一种替代方式告诉 Spring 容器上下文加载器类使用什么配置文件。我从不打扰它,但只是使用contextConfigLocation每当我需要配置自定义配置文件时。

这是我之前的 Spring 项目之一的示例(为了简洁起见,省略了一些配置):

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Spring Web Application example</display-name>

    <!-- Configurations for the root application context (parent context) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/jdbc/spring-jdbc.xml
            /WEB-INF/spring/security/spring-security-context.xml
        </param-value>
    </context-param>

    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/mvc/spring-mvc-servlet.xml
            </param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/admin/*</url-pattern>
    </servlet-mapping>

</web-app>

长答案

好的,首先让我们弄清楚一些重要时刻。我们正在处理两种类型的上下文:

  1. 根上下文(家长)
  2. 单独的 servlet 上下文 (child)

引用 Spring Framework API(撰写本文时版本 3.2.2)Web应用程序上下文 http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/context/WebApplicationContext.html(强调我的):

与通用应用程序上下文一样,Web 应用程序上下文是 分层的。每个应用程序有一个根上下文,而 应用程序中的每个 servlet(包括调度程序 servlet) MVC框架)有自己的子上下文.

也在这里:上下文层次结构 http://docs.spring.io/spring/docs/3.2.2.RELEASE/spring-framework-reference/html/testing.html#testcontext-ctx-management-ctx-hierarchies:

例如,如果您正在开发 Spring MVC Web 应用程序,您 通常会有一个通过 Spring 加载的 root WebApplicationContext 上下文加载监听器 and a 子 WebApplicationContext 加载通过 Spring 的 DispatcherServlet。这会导致父子上下文 共享组件和基础设施配置所在的层次结构 在根上下文中声明并在子上下文中使用 特定于网络的组件。

和这里:17.2 调度程序Servlet http://docs.spring.io/spring/docs/3.2.2.RELEASE/spring-framework-reference/html/mvc.html#mvc-servlet:

Spring 中的 ApplicationContext 实例可以划分范围。在 Web MVC 中 框架,每个DispatcherServlet都有自己的WebApplicationContext, 它继承了根中已经定义的所有bean Web应用程序上下文。这些继承的bean可以在 servlet 特定范围,并且您可以定义新的特定范围 bean 对于给定的 Servlet 实例来说是本地的。


现在让我们看看根应用程序上下文配置。这是一个例子:
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/daoContext.xml
            /WEB-INF/spring/applicationContext.xml
        </param-value>
    </context-param>
</web-app>


来自 Spring 官方文档(重点是我的):
5.14.4 Web 应用程序的便捷 ApplicationContext 实例化 http://docs.spring.io/spring/docs/3.2.2.RELEASE/spring-framework-reference/html/beans.html#context-create:

您可以以声明方式创建 ApplicationContext 实例通过使用, 例如,ContextLoader。当然你也可以创建 通过使用以下之一以编程方式实例化 ApplicationContext ApplicationContext 实现。

You can 使用 ContextLoaderListener 注册 ApplicationContext(参见上面的例子)

侦听器检查 contextConfigLocation 参数。如果 参数不存在,监听器使用 /WEB-INF/applicationContext.xml 作为默认值。当参数为 存在时,侦听器使用预定义的分隔字符串 分隔符(逗号、分号和空格)并将值用作 将搜索应用程序上下文的位置。蚂蚁式路径 也支持模式。示例为 /WEB-INF/*Context.xml 名称以“Context.xml”结尾的所有文件,位于 “WEB-INF”目录和 /WEB-INF/**/*Context.xml,用于所有此类文件 在“WEB-INF”的任何子目录中。


Spring 配置经常被分割到多个文件中。它更加符合逻辑和方便,尤其是在大型项目中。在我们的示例中,我们显式定义了两个配置 XML 文件:daoContext.xml and 应用程序上下文.xml在自定义位置:/WEB-INF/spring/。再说一遍,如果我们没有定义上下文配置位置, the 上下文加载监听器会尝试找到默认配置文件:/WEB-INF/applicationContext.xml.

NOTE:
The 根上下文是可选的。另请参阅这个答案:https://stackoverflow.com/a/7451389/814702 https://stackoverflow.com/a/7451389/814702

所以如果默认/WEB-INF/applicationContext.xml配置文件不适合您的需要,请使用上下文加载监听器随着<context-param> 上下文配置位置您可以在其中定义自定义配置文件定义根应用程序上下文.


接下来我们来看看个人(子)应用程序上下文。来自 Spring 官方文档(重点是我的):
17.2 调度程序Servlet http://docs.spring.io/spring/docs/3.2.2.RELEASE/spring-framework-reference/html/mvc.html#mvc-servlet

在初始化 DispatcherServlet 时,Spring MVC 会查找名为的文件
WEB-INF 目录中的 [servlet-name]-servlet.xml
你的 Web 应用程序并创建在那里定义的 bean,覆盖 全局中使用相同名称定义的任何 bean 的定义 范围。

考虑以下 DispatcherServlet Servlet 配置(在 web.xml 文件):

<web-app>

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

    <servlet-mapping>
        <servlet-name>golfing</servlet-name>
        <url-pattern>/golfing/*</url-pattern>
    </servlet-mapping>

</web-app>

关于 contextConfigLocation 和命名空间

从文档(强调我的):

完成上述 Servlet 配置后,您将需要一个名为
/WEB-INF/golfing-servlet.xml在您的申请中;这 文件将包含所有 Spring Web MVC 特定的组件 (豆子)。您可以更改此配置文件的确切位置 通过 Servlet 初始化参数(详细信息见下文)。
...
您可以自定义各个 DispatcherServlet 实例通过增加 Servlet 初始化参数(init-param 元素)到 Servlet web.xml 文件中的声明。列表见下表 支持的参数。

  • 上下文类:实现WebApplicationContext的类,它实例化此Servlet使用的上下文。默认情况下,使用 XmlWebApplicationContext。

  • 上下文配置位置:传递给上下文实例(由 contextClass 指定)的字符串,用于指示可以在哪里找到上下文。该字符串可能由多个字符串组成(使用逗号作为分隔符)以支持多个上下文。 如果多个上下文位置的 bean 定义了两次,则最新位置优先。

  • 名称空间:WebApplicationContext 的命名空间。默认为 [servlet 名称]-servlet。


现在我们来研究一下相关类的API文档。班上调度程序Servlet http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html扩展抽象类框架Servlet http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/servlet/FrameworkServlet.html。来自框架ServletAPI 文档(重点是我的):

将“contextConfigLocation”servlet init-param 传递给上下文 例如,将其解析为潜在的多个文件路径,这些路径可以是 用任意数量的逗号和空格分隔,例如
“测试servlet.xml, myServlet.xml”。如果没有明确指定,则上下文 实现应该从构建一个默认位置 servlet 的命名空间.

默认命名空间是“'servlet-name'-servlet”,例如“测试servlet” 对于 servlet 名称“test”(导致“/WEB-INF/test-servlet.xml” 默认位置与 XmlWebApplicationContext)。命名空间可以 也可以通过“命名空间”servlet init-param 显式设置.

这是摘录自框架Servlet源代码:
框架Servlet.java https://web.archive.org/web/20180311141859/http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.web.servlet/3.2.2/org/springframework/web/servlet/FrameworkServlet.java#FrameworkServlet.0DEFAULT_NAMESPACE_SUFFIX

....
/**
* Suffix for WebApplicationContext namespaces. If a servlet of this class is
* given the name "test" in a context, the namespace used by the servlet will
* resolve to "test-servlet".
*/
public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
....


默认上下文类框架Servlet is XmlWeb应用程序上下文 http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/context/support/XmlWebApplicationContext.html。来自XmlWeb应用程序上下文API 文档(重点是我的):

默认情况下,配置将从 根上下文的“/WEB-INF/applicationContext.xml”,以及 “/WEB-INF/test-servlet.xml”用于具有命名空间的上下文 “test-servlet”(例如带有以下内容的 DispatcherServlet 实例) servlet 名称“测试”)。

配置位置默认值可以通过以下方式覆盖 ContextLoader 和 servlet 的“contextConfigLocation”上下文参数 FrameworkServlet 的 init-param。配置位置可以表示 具体文件,如“/WEB-INF/context.xml”或 Ant 风格模式,如 “/WEB-INF/*-context.xml”(有关模式,请参阅 PathMatcher javadoc 细节)。

使用覆盖默认配置位置contextConfigLocation与上面根应用程序上下文的示例相同。

至于覆盖默认命名空间有一些重要的时刻。当您设置新的命名空间时,不要在它前面加上/WEB-INF并且不附加.xml to it。如果我们在源文件中查找以下内容,就可以发现其原因XmlWeb应用程序上下文 class:
XmlWebApplicationContext.java https://web.archive.org/web/20170709235533/http://grepcode.com/file/repository.springsource.com/org.springframework/org.springframework.web/3.2.2/org/springframework/web/context/support/XmlWebApplicationContext.java

...

/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

...

/**
* The default location for the root context is "/WEB-INF/applicationContext.xml",
* and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
* (like for a DispatcherServlet instance with the servlet-name "test").
*/
@Override
protected String[] getDefaultConfigLocations() {
    if (getNamespace() != null) {
        return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
    }
    else {
        return new String[] {DEFAULT_CONFIG_LOCATION};
    }
}

正如您所看到的,源代码说明了一切。

指定自定义命名空间的示例

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">


    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>spring/mvc/spring-mvc</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

结果是,不是使用默认命名空间来构造配置文件的路径,否则会是/WEB-INF/spring-mvc-servlet.xml,容器会寻找/WEB-INF/spring/mvc/spring-mvc.xml.

NOTE:
以上与设置自定义命名空间相关的说明均针对默认情况XmlWeb应用程序上下文 http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/context/support/XmlWebApplicationContext.html上下文类。人们可以指定一个替代类,例如AnnotationConfigWebApplicationContext http://docs.spring.io/spring/docs/3.2.2.RELEASE/javadoc-api/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.html,所以会有一些特殊的时刻。


结论

(恕我直言)它更容易使用contextConfigLocation参数来定义自定义配置文件,既适用于根应用程序上下文,也适用于各个上下文。唯一的区别是对于您使用的根应用程序上下文<context-param> within <web-app>元素,但不在特定的 servlet 内(也不要忘记侦听器类)。对于您使用的子上下文<init-param>嵌套在<servlet>元素对于每个特定的 servlet。请参阅我的示例配置(web.xml)在这篇文章的开头。

其他资源(好像以上还不够:-)):

  • Spring框架参考 文档 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/
  • Spring中applicationContext.xml和spring-servlet.xml的区别 https://stackoverflow.com/a/3652125/814702
  • Spring MVC 中 ApplicationContext 和 WebApplicationContext 有什么区别? https://stackoverflow.com/a/11709272/814702
  • Spring-MVC:什么是“上下文”和“命名空间”? https://stackoverflow.com/a/7451389/814702
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数 的相关文章

随机推荐

  • 如何设置 SBT 构建以在 Jenkins 测试失败时返回零退出代码?

    当我通过 SBT 在 Jenkins 中运行 Specs2 测试时 一旦一个测试失败 构建就会被标记为失败 由于 Jenkins 通常会区分构建失败和测试失败 所以我想改变这一点 我知道 Jenkins 中的构建失败是通过调用 SBT 的退
  • 使用带有 Django CSRF 保护的 angular2 http 请求的正确方法是什么?

    在Angular1中可以通过配置 http provider来解决这个问题 喜欢 app config function httpProvider httpProvider defaults xsrfCookieName csrftoken
  • 对 VBO 中的特定三角形使用不同的纹理

    我有 9 个由三角形组成的四边形 如下所示 我在用着VBO存储有关它们的数据 它们的位置和纹理坐标 我的问题是 是否可以仅使用一个来使四边形 5 具有与其余四边形不同的纹理VBO and shader 绿色代表纹理 1 黄色代表纹理 2 到
  • 如何使用 opencv 从字节显示视频?

    我正在开展一个项目 其中我们使用无线电调制解调器将数据 视频和遥测 从无人机传输到地面站 我们需要做的是实时显示视频 并能够知道 C 中的每一块遥测数据对应哪一帧 数据被解封装为遥测和视频 mpeg4 字节 由于我对 OpenCV 有一些经
  • 在python中读取.xlsx格式

    我必须在 python 中每 10 分钟读取一次 xlsx 文件 做到这一点最有效的方法是什么 我尝试过使用 xlrd 但它不读取 xlsx 根据他的文档 但我不能这样做 获取Unsupported format or corrupt fi
  • Pulp.solvers.PulpSolverError:PuLP:无法执行glpsol.exe

    我是 python 和优化的新手 我收到一些错误 请帮我解决 我尝试在运行 Anaconda 3 的 PyCharm 中运行下面提到的代码 from pulp import x LpVariable x 0 3 y LpVariable y
  • 在不刷新页面的情况下如何使用ajax/jQuery显示数据库中的值

    通过jQuery ajax将数据插入数据库后 同时从数据库获取值而不刷新页面如何使用codeigniter显示数据库值 这是我的代码 Script
  • Go TCP 读取是非阻塞的

    我正在尝试用 Go 创建服务器和客户端 我已经成功地与服务器和客户端进行通信 但我遇到的问题是golang中的TCP读取是非阻塞的 我想知道 golang 中的读取是否有可能像 C 中的读取一样阻塞 谢谢 EDIT 这是服务器的源代码 fu
  • Brython 完全是客户端吗?

    我有一段用Python编写的代码 我想将该代码放在网页中 Brython 似乎是将这两件事粘合在一起的最简单方法 但我没有可以在服务器端实际运行代码的服务器 Brython 是否需要服务器端代码 或者我可以通过 例如 Dropbox 便宜地
  • 具有多个构造函数的 C++ init 成员变量

    通常构造函数应该是这样的 ctor1 SmallSim SmallSim mSimInit false mServersCreated false mTotalCPUTime 0 如果我有多个构造函数会怎样 在我看来 如果我从第二个构造函数
  • HttpSecurity、WebSecurity 和 AuthenticationManagerBuilder

    谁能解释一下何时覆盖configure HttpSecurity configure WebSecurity and configure AuthenticationManagerBuilder 配置 AuthenticationManag
  • 以编程方式创建 dataList

    我正在尝试以编程方式创建一个表 其中一个单元格包含数据列表 下面是片段 CustomTag phone form class PhoneForm extends PolymerElement observable List
  • CameraX 多个后置摄像头

    我正在尝试使用 CameraX 实现自定义相机应用程序 鉴于现在很多新设备都有多个后置摄像头 我也想将其包括在内 所以基本上 用户可以选择使用哪个相机 我已使用 addCameraFilter 选项尝试了以下操作 val cameraSel
  • 在 Android 项目中使用“compileOnly”范围?

    我在项目中使用 Gradle 2 12 或更高版本 以及适当版本的 Android Gradle 插件 Gradle 2 12 引入了compileOnly配置 那么为什么当我尝试使用它时会出现错误呢 找不到参数的compileOnly 方
  • 为什么 mongodump 不备份索引?

    在阅读 mongodump 文档时 我发现了此信息 mongodump 在其备份数据中仅捕获数据库中的文档 不包含索引数据 mongorestore 或 mongod 必须在恢复数据后重建索引 考虑到索引也是数据库难题的关键部分 并且它们需
  • XmlAttribute 不适用于 XmlArray

    我在使用 XmlSerializer 生成以下 XML 结构时遇到问题
  • 动画窗口调整大小内容重新排列

    我看到许多主题 当调整窗口大小时 它会重新排列内容并带有轻微的动画 例如http wpexplorer me demo php theme pronto http wpexplorer me demo php theme pronto 如果
  • aws kinesis get-records 返回空数组

    我正在玩 Kinesis 我尝试了一个非常简单的示例 我先放一个样本记录 aws kinesis put records records Data Test data hemant PartitionKey 20150421 stream
  • 使用 O(n) 运行时查找范围内的元素

    我正在尝试编写一个函数 从用户接收一个大小为 N 的数组 其值在0 gt N 1之间 如果所有值在0 gt N之间 该函数应该返回 1 1 是否存在 否则返回 0 我们可以假设用户输入的数字只是有效值 0 gt N 1之间 示例 N 5 值
  • Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数

    我正在阅读 Spring MVC 的文档 并且有一个关于 init 参数的问题 如果有必要的话 我正在使用 Spring 3 2 contextConfigLocation 和命名空间有什么区别 contextConfigLocation