春季:命名空间VS在web.xml中的contextConfigLocation初始化参数(Spri

2019-08-19 14:28发布

我读了Spring MVC的文档和我有任何关于初始化参数的问题。 我使用Spring 3.2,如果它的问题。 是什么contextConfigLocation的和命名空间之间的区别? 只是针对指定在上下文类可以找到一个XML定义和命名空间属性的文件夹contextConfigLocation的是为指定文件名?

<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? 并应指定路径?

Answer 1:

TL; DR

刚刚成立的中值(S) contextConfigLocation每当你需要指定自定义配置文件。 这样,您将可以同时指定配置文件名称和它们的位置。

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>

长一点的回答

OK,首先让我们得到一些重要时刻清楚。 有两种类型的我们面对的情境:

  1. 根上下文 (父)
  2. 个人servlet上下文 (子)

Spring框架API(版本3.2.2在写这篇的时刻)的报价单的WebApplicationContext (重点煤矿):

像一般的应用环境中,Web应用程序上下文是分级的。 有每个应用程序的单个根上下文,而在应用程序(包括在MVC框架分发程序Servlet)每个Servlet都有自己的子女范围内

另外这里: 上下文层次 :

例如,如果你正在开发一个Spring MVC的Web应用程序,你会通常通过Spring的ContextLoaderListener加载根的WebApplicationContext,通过Spring的DispatcherServlet加载孩子的WebApplicationContext。 这导致在共享的组件和基础设施配置在根上下文的声明,并通过特定的网络组件的子上下文所消耗的父子上下文结构。

在这里: 17.2的DispatcherServlet :

在Spring中的ApplicationContext可以作用域。 在Web MVC框架中, 每个DispatcherServlet有它自己的WebApplicationContext,它继承了根WebApplicationContext定义的Bean。 这些继承的bean可以在特定的servlet范围的覆盖,并且可以定义新的特定范围,本地豆给定的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方便的ApplicationContext实例化的web应用程序 :

您可以通过使用,例如通过ContextLoader 声明创建的ApplicationContext。 当然,你也可以通过编程使用ApplicationContext实现的一个创建的ApplicationContext。

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

监听器检查contextConfigLocation的参数。 如果该参数不存在,听者使用/WEB-INF/applicationContext.xml的作为默认值 。 当参数不存在,听者通过使用分隔符(逗号,分号和空白)字符串分开,并使用值作为应用上下文将被搜索的位置。 Ant风格的路径模式,以及支持。 例子是/WEB-INF/*Context.xml为与“context.xml的”结尾的名称的所有文件,驻留在“WEB-INF”目录,/WEB-INF/**/*Context.xml,所有这些文件在“WEB-INF”的任何子目录。


常常Spring配置跨多个文件分割。 这是更合理,更方便,特别是在大型项目。 在我们的例子中,我们明确地定义了两个配置XML文件:daoContext.xmlapplicationContext.xml中的自定义位置: /WEB-INF/spring/ 。 同样,如果我们没有定义contextConfigLocation的 ,该会的ContextLoaderListener试图找到默认的配置文件: /WEB-INF/applicationContext.xml

注意:
根上下文是可选的 。 也看到这个答案: https://stackoverflow.com/a/7451389/814702

因此,如果默认/WEB-INF/applicationContext.xml配置文件不能满足您的需求,使用的ContextLoaderListener沿<context-param> contextConfigLocation的 ,你可以自定义配置文件(S) 来定义根应用程序上下文


接下来让我们来看看个人(子)应用程序上下文 。 从官方Spring文档(重点煤矿):
17.2的DispatcherServlet

在DispatcherServlet的初始化过程,Spring MVC的查找一个文件名为
Web应用程序的WEB-INF目录[servlet的名称] -servlet.xml后缀 ,并创建定义的bean,会覆盖在全球范围内的名字相同的Bean的定义。

考虑以下DispatcherServlet的配置(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特定组件(bean)的。 您可以通过一个Servlet初始化参数更改此配置文件的确切位置(详见下文)。
...
您可以通过添加Servlet的初始化参数(NIT-param元素)在web.xml文件中的Servlet声明定制个人DispatcherServlet的实例 。 请参阅下表为支持的参数列表。

  • contextClass:实现WebApplicationContext,其实例由这个servlet使用的上下文类。 默认情况下,使用使用XmlWebApplicationContext。

  • 的contextConfigLocation:传递给上下文实例(由contextClass指定)字符串来指示上下文(多个)可以找到。 字符串由潜在的多个串(使用逗号作为分隔符)来支持多个上下文。 在被定义两次豆多上下文的情况下,最新的位置优先。

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


现在,让我们研究API文档的相关类。 类的DispatcherServlet扩展抽象类FrameworkServlet的 。 从FrameworkServlet的 API文档(重点煤矿):

传递一个“的contextConfigLocation” servlet初始化-PARAM上下文实例,解析它为能够由任何数量的逗号和空格的分离可能的多个文件路径,如
“测试servlet.xml中,myServlet.xml”。 如果没有明确指定,上下文实现应该从servlet的命名空间建立一个默认位置

默认命名空间是“'servlet的name'小服务程序”,例如‘测试的servlet’为一个servlet名‘测试’(领导与XmlWebApplicationContext一个‘/WEB-INF/test-servlet.xml’默认位置)。 该命名空间还可以通过“命名空间” servlet初始化-PARAM明确设置

这是从FrameworkServlet的源代码的摘录:
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文档(重点煤矿):

默认情况下,该配置将来自“/WEB-INF/applicationContext.xml的”为根上下文,而“/WEB-INF/test-servlet.xml”采取与命名空间“测试的servlet”(上下文等对于与Servlet的名称是“test”)一个DispatcherServlet的实例。

的配置位置的默认值可通过“的contextConfigLocation”的ContextLoader的上下文PARAM和FrameworkServlet的的servlet初始化-PARAM覆盖 。 配置位置既可以表示类似的“/WEB-INF/context.xml”或Ant风格的图案,如“/WEB-INF/*-context.xml”(见图案细节的PathMatcher的javadoc)的具体文件。

覆盖使用默认的配置位置contextConfigLocation是相同的根应用上下文中的上述示例。

作为覆盖默认命名空间有一些重要的时刻。 当您设置一个新的命名空间, 不加前缀/WEB-INF ,不附加.xml 。 其原因可如果我们对XMLWebApplicationContext类的源文件中查找发现:
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

注意:
有关设置自定义命名空间中的上述说明是默认XmlWebApplicationContext上下文类。 人们可以指定其他类,如AnnotationConfigWebApplicationContext ,所以会有一些特别的时刻。


结论

这是(恕我直言)使用更容易contextConfigLocation参数来定义自定义配置文件,既是根应用上下文,并为个别的背景。 唯一的区别是,对于根应用程序上下文使用<context-param>中的<web-app>元素,但不是一个特定的servlet中(也不要忘了监听器类)。 而您所使用的子上下文<init-param>嵌套在里面<servlet> 为每个特定的servlet元素。 看到这篇文章的最开始我的示例配置文件(web.xml)。

其他资源(好像上面是不够的:-)):

  • Spring框架参考文档
  • 在Spring的applicationContext.xml和弹簧servlet.xml中的区别
  • 是什么在Spring MVC的ApplicationContext和WebApplicationContext的区别?
  • Spring的MVC:是什么“背景”和“命名空间”?


Answer 2:

我觉得幸运的路克的回答有很多有用的信息,但它并没有回答这个问题。 特别是,如何“命名空间”和“contextConfigLocation的”参数一起工作?

我能找到具体的答案只有一个地方是源代码:

  • 将用于建设一个默认上下文的配置位置的命名空间 paremeter设置自定义命名空间
  • contextConfigLocation的参数显式设置,而不是依靠从命名空间内置的默认位置上下文的配置位置,


Answer 3:

是什么contextConfigLocation的和命名空间之间的区别? contextConfigLocation的用于指定的Spring配置文件的路径,这意味着他们将被初始化。 命名空间用来指定Spring MVC中的DispatcherServlet的路径和名称。 默认值是[Dispatcher_name]-servlet.xml ,这里是一个例子:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>namespace</param-name>
        <param-value>config/spring-mvc</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Spring将搜索要使用的文件,因为它是由的路径MVC配置/WEB-INF/config/spring-mvc.xml
只对指定的文件夹意味着contextConfigLocation的文意类可以找到一个XML定义

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/app-*.xml</param-value>
</context-param>

上面的代码表明,当应用程序启动春季将加载所有这些名称与“APP-”开始,并在WEB-INF / config目录“的.xml”结束的文件。

它应该使用/WEB-INF/application-context.xml? 并应指定路径?
通过以上所有我们可以知道,构式弹簧,当我们需要指定的完整路径和通用文件名,当用SpringMVC只有我们应该指定路径的例子(如果它位于一个目录,不包括WEB-INF目录)和名称(不包括扩展名)。
希望能帮助你:)



文章来源: Spring: namespace vs contextConfigLocation init parameters in web.xml