Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数 [英] Spring: namespace vs contextConfigLocation init parameters in web.xml

查看:27
本文介绍了Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am reading the documentation for Spring MVC and I have a question regarding the init params. I am using Spring 3.2 if it matter. What is the difference between the contextConfigLocation and namespace? Is the contextConfigLocation meant only for specifying the folders where the context class can find a XML definition and the namespace attribute is meant for specifying the file name?

<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 吗?你应该指定路径吗?

Is this correct? Should it use /WEB-INF/application-context.xml? And should you specify paths?

推荐答案

TL;DR

只要您需要指定自定义配置文件,只需为 contextConfigLocation 设置值.这样,您将同时指定配置文件名及其位置.

TL;DR

Just set the value(s) for the contextConfigLocation whenever you need to specify custom config files. This way you will be specifying both the config file names and their locations.

namespace 本质上是告诉 Spring 容器上下文加载器类使用什么配置文件的另一种方式.我从不理会它,只是在需要配置自定义配置文件时使用 contextConfigLocation.

The namespace is essentially an alternative way of telling Spring container context loader class what config file to use. I never bother with it, but just use contextConfigLocation whenever I need to configure custom config files.

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

Here is an example from one of my previous Spring projects (some of the configurations omitted for the sake of brevity):

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>

<小时>

长答案

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


Long answer

OK, first let's get some important moments clear. There are two types of contexts we are dealing with:

  1. 根上下文(父级)
  2. 单独的 servlet 上下文(子)
  1. root context (parent)
  2. individual servlet context (child)

引用 Spring Framework API(在撰写本文时为 3.2.2 版)的 WebApplicationContext(重点是我的):

Quote from the Spring Framework API (version 3.2.2 at the moment of writing this) for the WebApplicationContext (emphasis mine):

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

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.

也在这里:上下文层次结构:

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

For example, if you are developing a Spring MVC web application you will typically have a root WebApplicationContext loaded via Spring's ContextLoaderListener and a child WebApplicationContext loaded via Spring's DispatcherServlet. This results in a parent-child context hierarchy where shared components and infrastructure configuration are declared in the root context and consumed in the child context by web-specific components.

这里:17.2 DispatcherServlet:

Spring 中的 ApplicationContext 实例可以设置范围.在 Web MVC 中框架,每个 DispatcherServlet 都有自己的 WebApplicationContext,它继承了根中已经定义的所有beanWebApplicationContext.这些继承的 bean 可以在servlet 特定的范围,您可以定义新的特定范围的 bean本地给定的 Servlet 实例.

ApplicationContext instances in Spring can be scoped. In the Web MVC framework, each DispatcherServlet has its own WebApplicationContext, which inherits all the beans already defined in the root WebApplicationContext. These inherited beans can be overridden in the servlet-specific scope, and you can define new scope-specific beans local to a given Servlet instance.


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


Now let's see the root application context configuration. Here is an example:
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 实例化:

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

You can create ApplicationContext instances declaratively by using, for example, a ContextLoader. Of course you can also create ApplicationContext instances programmatically by using one of the ApplicationContext implementations.

您可以使用 ContextLoaderListener 注册一个 ApplicationContext(见上面的例子)

You can register an ApplicationContext using the ContextLoaderListener (see the example above)

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

The listener inspects the contextConfigLocation parameter. If the parameter does not exist, the listener uses /WEB-INF/applicationContext.xml as a default. When the parameter does exist, the listener separates the String by using predefined delimiters (comma, semicolon and whitespace) and uses the values as locations where application contexts will be searched. Ant-style path patterns are supported as well. Examples are /WEB-INF/*Context.xml for all files with names ending with "Context.xml", residing in the "WEB-INF" directory, and /WEB-INF/**/*Context.xml, for all such files in any subdirectory of "WEB-INF".


Spring 配置经常被拆分到多个文件中.更合乎逻辑和方便,尤其是在大型项目中.在我们的示例中,我们在自定义位置明确定义了两个配置 XML 文件:daoContext.xmlapplicationContext.xml:/WEB-INF/spring/.同样,如果我们没有定义 contextConfigLocationContextLoaderListener 将尝试定位默认配置文件:/WEB-INF/applicationContext.xml.


Quite often Spring configuration is split across multiple files. It's more logical and convenient, especially in the large-scale projects. In our example we explicitly defined two configuration XML files: daoContext.xml and applicationContext.xml in the custom location: /WEB-INF/spring/. Again, had we not defined contextConfigLocation, the ContextLoaderListener would try to locate the default config file: /WEB-INF/applicationContext.xml.

注意:
根上下文是可选的.另请参阅此答案:https://stackoverflow.com/a/7451389/814702

NOTE:
The root context is optional. Also see this answer: https://stackoverflow.com/a/7451389/814702

因此,如果默认的 /WEB-INF/applicationContext.xml 配置文件不适合您的需求,请使用 ContextLoaderListener<context-param> contextConfigLocation 您可以在其中定义自定义配置文件定义根应用程序上下文.

So if the default /WEB-INF/applicationContext.xml config file does not suit your needs, use ContextLoaderListener along with <context-param> contextConfigLocation where you can define custom config file(s) to define root application context.


接下来让我们看看单个(子)应用程序上下文.来自官方 Spring 文档(重点是我的):
17.2 DispatcherServlet


Next let's see the individual (child) application context. From the official Spring documentation (emphasis mine):
17.2 The DispatcherServlet

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

Upon initialization of a DispatcherServlet, Spring MVC looks for a file named
[servlet-name]-servlet.xml in the WEB-INF directory
of your web application and creates the beans defined there, overriding the definitions of any beans defined with the same name in the global scope.

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

Consider the following DispatcherServlet Servlet configuration (in the web.xml file):

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


来自文档(重点是我的):

From the documentation (emphasis mine):

有了上面的 Servlet 配置,您将需要一个名为
的文件/WEB-INF/golfing-servlet.xml 在您的应用程序中;这个文件将包含所有 Spring Web MVC 特定的组件(豆子).您可以更改此配置文件的确切位置通过 Servlet 初始化参数(详见下文).
...
您可以通过添加自定义 DispatcherServlet 实例Servlet 初始化参数(init-param 元素)到 Servletweb.xml 文件中的声明.列表见下表支持的参数.

With the above Servlet configuration in place, you will need to have a file called
/WEB-INF/golfing-servlet.xml in your application; this file will contain all of your Spring Web MVC-specific components (beans). You can change the exact location of this configuration file through a Servlet initialization parameter (see below for details).
...
You can customize individual DispatcherServlet instances by adding Servlet initialization parameters (init-param elements) to the Servlet declaration in the web.xml file. See the following table for the list of supported parameters.

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

  • contextClass: Class that implements WebApplicationContext, which instantiates the context used by this Servlet. By default, the XmlWebApplicationContext is used.

contextConfigLocation:传递给上下文实例(由 contextClass 指定)的字符串,以指示可以找到上下文的位置.该字符串可能包含多个字符串(使用逗号作为分隔符)以支持多个上下文.如果 bean 的多个上下文位置被定义两次,则最新位置优先.

contextConfigLocation: String that is passed to the context instance (specified by contextClass) to indicate where context(s) can be found. The string consists potentially of multiple strings (using a comma as a delimiter) to support multiple contexts. In case of multiple context locations with beans that are defined twice, the latest location takes precedence.

namespace:WebApplicationContext 的命名空间.默认为 [servlet-name]-servlet.

namespace: Namespace of the WebApplicationContext. Defaults to [servlet-name]-servlet.


现在让我们研究相关类的 API 文档.类 DispatcherServlet 扩展抽象类 FrameworkServlet.来自 FrameworkServlet API 文档(重点是我的):


Now let's research the API documentation for the related classes. The class DispatcherServlet extends abstract class FrameworkServlet. From the FrameworkServlet API docs (emphasis mine):

将contextConfigLocation"servlet init-param 传递给上下文例如,将其解析为可能的多个文件路径由任意数量的逗号和空格分隔,例如
测试servlet.xml,myServlet.xml".如果没有明确指定,则上下文实现应该从servlet 的命名空间.

Passes a "contextConfigLocation" servlet init-param to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, like
"test-servlet.xml, myServlet.xml". If not explicitly specified, the context implementation is supposed to build a default location from the namespace of the servlet.

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

The default namespace is "'servlet-name'-servlet", e.g. "test-servlet" for a servlet-name "test" (leading to a "/WEB-INF/test-servlet.xml" default location with XmlWebApplicationContext). The namespace can also be set explicitly via the "namespace" servlet init-param.

这是 FrameworkServlet 源代码的摘录:
FrameworkServlet.java

This is the excerpt from the FrameworkServlet source code:
FrameworkServlet.java

....
/**
* 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";
....


FrameworkServlet 的默认上下文类是 XmlWebApplicationContext.来自 XmlWebApplicationContext API 文档(重点是我的):


The default context class for FrameworkServlet is XmlWebApplicationContext. From the XmlWebApplicationContext API docs (emphasis mine):

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

By default, the configuration will be taken from "/WEB-INF/applicationContext.xml" for the root context, and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test").

配置位置默认值可以通过ContextLoader 和 servlet 的contextConfigLocation"上下文参数FrameworkServlet 的初始化参数.配置位置可以表示具体文件,如/WEB-INF/context.xml"或 Ant 风格的模式,如/WEB-INF/*-context.xml"(模式见PathMatcher javadoc详情).

The config location defaults can be overridden via the "contextConfigLocation" context-param of ContextLoader and servlet init-param of FrameworkServlet. Config locations can either denote concrete files like "/WEB-INF/context.xml" or Ant-style patterns like "/WEB-INF/*-context.xml" (see PathMatcher javadoc for pattern details).

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

Overriding default config locations using contextConfigLocation is the same as in the above example for the root application context.

至于覆盖默认命名空间,有一些重要的时刻.当你设置一个新的命名空间时,不要在它前面加上 /WEB-INF 也不要在它后面附加 .xml.如果我们查看 XmlWebApplicationContext 类的源文件,可以发现其原因:
XmlWebApplicationContext.java

As for the overriding the default namespace there are some important moments. When you set a new namespace, don't prepend it with /WEB-INF and don't append .xml to it. The reason for that can be discovered if we look in the source file for the XmlWebApplicationContext class:
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};
    }
}

如您所见,源代码说明了一切.

As you can see, the source code says it all.


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.

The result is that, instead of using the default namespace for constructing the path to the config file, that would otherwise be /WEB-INF/spring-mvc-servlet.xml, the container will look for /WEB-INF/spring/mvc/spring-mvc.xml.

注意:
上面关于设置自定义命名空间的说明是针对默认的XmlWebApplicationContext 上下文类.可以指定一个替代类,例如 AnnotationConfigWebApplicationContext,所以会有一些特殊的时刻.

NOTE:
The above explanations related to the setting custom namespace are for the default XmlWebApplicationContext context class. One can specify an alternative class, like AnnotationConfigWebApplicationContext, so there will be some special moments for that.

(恕我直言)使用 contextConfigLocation 参数来定义自定义配置文件(针对根应用程序上下文和单个上下文)要容易得多.唯一的区别是,对于根应用程序上下文,您在 元素中使用 ,但不使用在特定的 servlet 中(也不要忘记侦听器类).对于子上下文,您使用 <init-param> 嵌套在 <servlet> 元素中对于每个特定的 servlet.请参阅本文开头的示例配置 (web.xml).

It is (IMHO) much more easier to use contextConfigLocation parameter to define custom config files, both for the root application context and for the individual contexts. The only difference is that for the root application context you use <context-param> within <web-app> element, but NOT within a specific servlet (also don't forget the listener class). And for the child context you use <init-param> nested inside the <servlet> element for each specific servlet. See my example configurations (web.xml) in the very beginning of this post.

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

Additional resources (as if the above was not enough :-)):

这篇关于Spring:web.xml 中的命名空间与 contextConfigLocation 初始化参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆