我正在阅读Spring MVC的文档,我有一个关于init params的问题。如果重要,我正在使用Spring 3.2。 contextConfigLocation和命名空间有什么区别? contextConfigLocation是否仅用于指定上下文类可以找到XML定义的文件夹,而namespace属性用于指定文件名?
<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吗?你应该指定路径吗?
答案 0 :(得分:166)
只要您需要指定自定义配置文件,只需设置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>
好的,首先让我们清楚一些重要的时刻。我们正在处理两种类型的上下文:
引用WebApplicationContext(强调我的)的Spring Framework API(编写本文时的版本3.2.2):
与通用应用程序上下文一样,Web应用程序上下文也是如此 分层。 每个应用程序都有一个根上下文,而 应用程序中的每个servlet(包括一个调度程序servlet) MVC框架)有自己的子上下文。
例如,如果您正在开发Spring MVC Web应用程序 通常会通过Spring加载根WebApplicationContext ContextLoaderListener 和一个子WebApplicationContext通过加载 Spring的DispatcherServlet 。这导致父子上下文 共享组件和基础结构配置的层次结构 在根上下文中声明并在子上下文中使用 特定于网络的组件。
在这里:17.2 The DispatcherServlet:
Spring中的ApplicationContext实例可以作用域。在Web MVC中 框架,每个DispatcherServlet都有自己的WebApplicationContext, 它继承了已在根中定义的所有bean WebApplicationContext的即可。这些继承的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 Convenient ApplicationContext instantiation for web applications:
您可以使用声明性地创建ApplicationContext实例, 例如,ContextLoader。当然你也可以创建 ApplicationContext实例以编程方式使用其中一个 ApplicationContext实现。
您可以使用ContextLoaderListener 注册ApplicationContext (见上面的例子)
侦听器检查contextConfigLocation参数。 如果 参数不存在,监听器使用 /WEB-INF/applicationContext.xml作为默认值。参数的时候 如果存在,则侦听器使用预定义分隔String 分隔符(逗号,分号和空格)并将值用作 将搜索应用程序上下文的位置。蚂蚁风格的道路 也支持模式。示例是/WEB-INF/*Context.xml for 名称以&#34结尾的所有文件; Context.xml&#34;,驻留在 &#34; WEB-INF&#34;所有此类文件的目录和/WEB-INF/**/*Context.xml 在&#34; WEB-INF&#34;的任何子目录中。
Spring配置通常分为多个文件。它更合乎逻辑,更方便,特别是在大型项目中。在我们的示例中,我们在自定义位置/WEB-INF/spring/
中明确定义了两个配置XML文件: daoContext.xml 和 applicationContext.xml 。同样,如果我们没有定义 contextConfigLocation , ContextLoaderListener 将尝试找到默认配置文件: /WEB-INF/applicationContext.xml
。
注意:
根上下文是可选的。另请参阅此答案:https://stackoverflow.com/a/7451389/814702
因此,如果默认 /WEB-INF/applicationContext.xml
配置文件不符合您的需求,请使用 ContextLoaderListener 以及<context-param>
contextConfigLocation 您可以在其中定义自定义配置文件以定义根应用程序上下文。
接下来让我们看一下个人(子)应用程序上下文。从官方的Spring文档(强调我的):
17.2 The DispatcherServlet
在初始化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>
从文档(强调我的):
上面的Servlet配置到位后,您需要有一个名为
的文件 您的申请中/WEB-INF/golfing-servlet.xml
;这个 file将包含所有Spring Web MVC特定的组件 (豆子)。您可以更改此配置文件的确切位置 通过Servlet初始化参数(详见下文) ...
您可以通过添加自定义单个DispatcherServlet实例 Servlet初始化参数(init-param元素)到Servlet web.xml文件中的声明。有关列表,请参阅下表 支持的参数。
contextClass :实现WebApplicationContext的类,它实例化此Servlet使用的上下文。默认情况下,使用XmlWebApplicationContext。
contextConfigLocation :传递给上下文实例(由contextClass指定)的字符串,用于指示可以找到上下文的位置。该字符串可能包含多个字符串(使用逗号作为分隔符)以支持多个上下文。 如果多个上下文位置的bean定义了两次,则最新位置优先。
命名空间 :WebApplicationContext的命名空间。默认为[servlet-name] -servlet。
现在让我们研究相关类的API文档。类DispatcherServlet扩展了抽象类FrameworkServlet。来自 FrameworkServlet API文档(强调我的):
传递&#34; contextConfigLocation&#34; servlet init-param到上下文 实例,将其解析为可能的多个文件路径 由任意数量的逗号和空格分隔,如
&#34;测试servlet.xml中, myServlet.xml&#34 ;. 如果未明确指定,则为上下文 实现应该从中构建一个默认位置 servlet的命名空间。默认命名空间是&#34;&#39; servlet-name&#39; -servlet&#34;,例如&#34;测试的servlet&#34; 对于servlet-name&#34; test&#34; (导致&#34; /WEB-INF/test-servlet.xml" XmlWebApplicationContext的默认位置)。 命名空间可以 也可以通过&#34;命名空间&#34;显式设置。 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文档(强调我的):
默认情况下,将从中获取配置 &#34; /WEB-INF/applicationContext.xml"对于根上下文,和 &#34; /WEB-INF/test-servlet.xml"对于具有命名空间的上下文 &#34;测试的servlet&#34; (对于带有的DispatcherServlet实例 servlet-name&#34; test&#34;)。
可以通过以下方式覆盖配置位置默认值 &#34; contextConfigLocation的&#34; ContextLoader和servlet的context-param FrameworkServlet的init-param 。配置位置可以表示 具体文件如&#34; /WEB-INF/context.xml"或蚂蚁式的图案 &#34; / WEB-INF / * - context.xml的&#34; (有关模式,请参阅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 )。
其他资源(好像上面的内容还不够: - )):
答案 1 :(得分:4)
我认为LuckyLuke的答案有很多有用的信息,但它没有回答这个问题。特别是,“namespace”和“contextConfigLocation”参数如何协同工作?
我能找到具体答案的唯一地方是源代码:
答案 2 :(得分:3)
contextConfigLocation和命名空间有什么区别?
contextConfigLocation用于指定spring配置文件的路径,这意味着它们将被初始化。 namespace用于指定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将通过/WEB-INF/config/spring-mvc.xml
的路径搜索要用作mvc配置的文件。
contextConfigLocation是否仅用于指定上下文类可以找到XML定义的文件夹
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/app-*.xml</param-value>
</context-param>
上面的代码显示,当应用程序启动Spring时,将加载所有名称以'app-'开头并以WEB-INF / config目录中的'.xml'结尾的文件。
它应该使用/WEB-INF/application-context.xml吗?你应该指定路径吗?
通过上面的例子,我们可以知道在配置Spring时我们需要指定完整路径和通用文件名,当SpringMVC只指定路径时(如果它位于目录中,不包括WEB-INF目录)和名称(不包括扩展名)。
希望能帮到你:)。