当前位置: 首页 > 知识库问答 >
问题:

Spring:web.xml中的namespace vs contextConfigLocation初始化参数

江亮
2023-03-14
<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?您是否应该指定路径?

共有1个答案

濮阳征
2023-03-14

只要在需要指定自定义配置文件时为ContextConfigLocation设置值即可。这样,您将同时指定配置文件名和它们的位置。

命名空间本质上是告诉Spring容器上下文加载器类要使用什么配置文件的另一种方法。我从不费心,只要在需要配置自定义配置文件时使用ContextConfigLocation即可。

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

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

与泛型应用程序上下文一样,web应用程序上下文也是分层的。每个应用程序都有一个根上下文,而应用程序中的每个servlet(包括MVC框架中的一个dispatcher servlet)都有自己的子上下文。

这里还有:上下文层次结构:

例如,如果您正在开发一个Spring MVC web应用程序,那么通常会有一个根WebApplicationContext通过Spring的ContextLoaderListener加载,一个子WebApplicationContext通过Spring的DispatcherServlet加载。这将导致父子上下文层次结构,其中共享组件和基础结构配置在根上下文中声明,并由特定于Web的组件在子上下文中使用。

<?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实例化:

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

您可以使用ContextLoaderListener注册ApplicationContext(参见上面的示例)

初始化DispatcherServlet时,Spring MVC在web应用程序的WEB-INF目录中查找名为
[servlet-name]-servlet.xml的文件,并创建在该目录中定义的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>


现在让我们研究相关类的API文档。类DispatcherServlet扩展了抽象类FrameworkServlet。从FrameworkServlet API文档(强调我的):

将“ContextConfigLocation”servlet init-param传递给上下文实例,并将其解析为可能的多个文件路径,这些路径可以由任意数量的逗号和空格分隔,如
“test-servlet.xml,myservlet.xml”。如果没有显式指定,上下文实现应该从servlet的名称空间构建一个默认位置。

默认的名称空间是“'servlet-name'-servlet”,例如servlet名为“test”的名称为“test-servlet”(导致XmlWebApplicationContext的默认位置为“/web-inf/test-servlet.xml”)。还可以通过“namespace”servlet init-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”,对于名称空间为“test-servlet”的上下文,配置取自“/web-inf/test-servlet.xml”(就像对于servlet-name为“test”的DispatcherServlet实例一样)。

对于覆盖默认名称空间,有一些重要的时刻。设置新的命名空间时,不要在它前面加上/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};
    }
}

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

<?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>
    null
 类似资料:
  • 问题内容: 我正在阅读Spring MVC的文档,并且对初始化参数有疑问。如果有关系,我正在使用Spring 3.2。contextConfigLocation和名称空间之间有什么区别?contextConfigLocation是否仅用于指定上下文类可以在其中找到XML定义的文件夹,而namespace属性用于指定文件名? 这个对吗?是否应使用/WEB-INF/application-contex

  • 上一节中我们给大家介绍了Fullpage的基本用法,可能很多用户有个性化的需求,没关系Fullpage提供了多个参数,我们可以配置这些参数,满足我们项目的需求。 controlArrows 默认值:true,决定是否使用控制箭头向左或向右移动幻灯片。 verticalCentered 默认值:true,决定是否初始化后,是否垂直居中网页的内容,如果你想自定义元素的位置,那么你可以设置为false,

  • 如下 ServletContext 接口方法允许 servlet 访问由应用开发人员在Web 应用中的部署描述符中指定的上下文初始化参数: getInitParameter getInitParameterNames 应用开发人员使用初始化参数来表达配置信息。代表性的例子是一个网络管理员的 e-mail 地址,或保存关键数据的系统名称。

  • 问题内容: 我想像这样使用Self in init参数: 我知道我可以在这里使用“ A”,但是我想实现这一点,如果某个类从A继承,那么它的初始化器将知道操作是它的类类型,而不仅仅是A。所以例如,如果我这样写: 然后,我可以使用: 这可能吗? 问题答案: 不必使用或在每个初始化器中使用,您可以简单地重写每个子类的初始化器以使用其自己的类型为。 之所以起作用,是因为的初始值设定项声明的类型应符合,并且

  • 问题内容: 我应该传递什么值来为N个项目创建有效的/ 基于结构的结构? 在中,有效数字为N(N已假定未来增长)。a的参数应该是什么?((int)(N * 0.75d),0.75d)?更多?减?更改负载系数有什么影响? 问题答案: 关于负载因子,我将简单引用HashMap javadoc : 通常,默认负载因子(.75)在时间和空间成本之间提供了很好的折衷。较高的值会减少空间开销,但会增加查找成本(

  • 问题内容: 如果没有明确指出它是String [],那么第一次调用someMethod怎么不编译? 使用数组初始化器创建String []数组很好,但是不能使用它传递参数。花括号是否以其他方式用于传递参数,从而使我期望其表现出轨? 编译器错误如下: Moo类型的someMethod(String [])方法不适用于参数(字符串,字符串,字符串) 问题答案: 您只能在声明数组变量或在数组创建表达式(