Java Spring Servlet项目web.xml中contextConfigLocation的加载顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27539610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Order of loading contextConfigLocation in web.xml of Spring Servlet project
提问by ecbrodie
Suppose that I have a Spring Javaproject and I am trying to configure it as a web server servlet. Here is a stripped-down version of the web.xmlfile:
假设我有一个Spring Java项目并且我试图将它配置为一个 Web 服务器 servlet。这是web.xml文件的精简版:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/generalApplicationContext.xml
</param-value>
</context-param>
<servlet>
<servlet-name>my-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>my-servlet</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
The key thing to note here is that I have specified two XML files to be loaded. One is general for my entire application, while the other is specific to the "my-servlet" servlet. For a setup with just one servlet-mapping, this wouldn't make sense. However, my project has multiple servlet-mappings and each one has specific Spring settings to them.
这里要注意的关键是我指定了两个要加载的 XML 文件。一个适用于我的整个应用程序,而另一个特定于“my-servlet”servlet。对于只有一个 servlet 映射的设置,这没有意义。但是,我的项目有多个 servlet 映射,每个映射都有特定的 Spring 设置。
My Question:Which contextConfigLocation is going to be loaded first by Spring? Will it be the generalApplicationContext.xml or will it be the specificApplicationContext.xml? More importantly, does the order of loading even matter? From my debugging efforts, it seems apparent that it does because I get different errors when I move some independent Spring configuration from one file to the other.
我的问题:Spring 将首先加载哪个 contextConfigLocation?它是generalApplicationContext.xml 还是specificApplicationContext.xml?更重要的是,加载顺序是否重要?从我的调试工作来看,这似乎很明显,因为当我将一些独立的 Spring 配置从一个文件移动到另一个文件时,我得到了不同的错误。
NB:Whether or not using multiple spring configurations for multiple servlet mappings is a good practice is debatable. Same goes for using XML config instead of the new Java config. But that's not what I'm trying to ask here. Let's try to focus on my main question.
注意:对多个 servlet 映射使用多个 spring 配置是否是一个好的做法是有争议的。使用 XML 配置而不是新的 Java 配置也是如此。但这不是我在这里想问的。让我们试着把注意力集中在我的主要问题上。
采纳答案by shazin
generalApplicationContext.xml
is the one that will be loaded first because it is the ApplicationContext
loaded with the ContextLoaderListener
generalApplicationContext.xml
是第一个加载的,因为它ApplicationContext
加载了ContextLoaderListener
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/generalApplicationContext.xml
</param-value>
</context-param>
specificApplicationContext.xml
is actually a Child Context of the Above loaded generalApplicationContext.xml
and it will be a WebApplicationContext
specificApplicationContext.xml
实际上是上面加载的子上下文,generalApplicationContext.xml
它将是一个WebApplicationContext
<servlet>
<servlet-name>my-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>my-servlet</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
And yes the order of loading does matter. Because when the parent context is loaded all the required dependencies must be fulfilled.
是的,加载顺序很重要。因为当加载父上下文时,必须满足所有必需的依赖项。
回答by Ankur Singhal
The below part loads the context file and create the ApplicationContext. This context might, for instance, contain components such as middle-tier transactional services, data access objects, or other objects that you might want to use (and re-use) across the application. There will be one application context per application.
以下部分加载上下文文件并创建ApplicationContext。例如,此上下文可能包含诸如中间层事务服务、数据访问对象或您可能希望在整个应用程序中使用(和重用)的其他对象等组件。每个应用程序将有一个应用程序上下文。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/generalApplicationContext.xml
</param-value>
</context-param>
The other context is the WebApplicationContextwhich is the child context of the application context. Each DispatcherServlet
defined in a Spring web application will have an associated WebApplicationContext
. The initialization of the WebApplicationContext
happens like this:
另一个上下文是WebApplicationContext,它是应用程序上下文的子上下文。每个DispatcherServlet
在 Spring Web 应用程序中定义的都将有一个关联的WebApplicationContext
. 的初始化是这样WebApplicationContext
发生的:
<servlet>
<servlet-name>my-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/specificApplicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
回答by Srinivas Rampelli
If you are having ContextLoaderListenerin your web.xml spring will load the generalApplicationContext.xmlfirst. This will create beans and provide them all Servlets and Filters. This xml should have the common classes, beans which are used in your application.
如果您的 web.xml中有ContextLoaderListener,则 spring 将首先加载generalApplicationContext.xml。这将创建 bean 并为它们提供所有 Servlet 和过滤器。这个 xml 应该有你的应用程序中使用的公共类,bean。
Later spring container will load the specificApplicationContext.xml, because you have load on startup in the servlet config. If you don't specify the load on start up, this specificApplicationContext.xmlwill load when the first requestcomes to your application with the specific url-pattern.
稍后 spring 容器将加载specificApplicationContext.xml,因为您在 servlet 配置中启动时加载。如果您没有在启动时指定负载,那么当第一个请求到达您的具有特定 url-pattern 的应用程序时,将加载这个specificApplicationContext.xml。
As your question when you move you springconfig from one config to another this will change the application resource availability to the container. If you specify the Controller beans in generalApplicationContext.xml and you don't specify them in specificApplicationContext.xml then your DispatcherServlet wont find the mappings, so you will see 404 error.
作为您将 springconfig 从一个配置移动到另一个配置时的问题,这将更改容器的应用程序资源可用性。如果您在 generalApplicationContext.xml 中指定控制器 bean 而您没有在 specificApplicationContext.xml 中指定它们,那么您的 DispatcherServlet 将找不到映射,因此您将看到 404 错误。
If you want to create some bean objects on-demand you can create one more servlet-config to load that specific specificConfigurationFile2.xml, and map to the url-pattern.
如果您想按需创建一些 bean 对象,您可以再创建一个 servlet-config 来加载特定的 ConfigurationFile2.xml,并映射到 url-pattern。
回答by Shailendra
What better way to actually have the Spring debug logs tell you itself the order.
If you want to get into the code you can also take a look at the org.springframework.web.servlet.FrameworkServlet
(DispatcherServlet
extends this class) Just enable the logger "org.springframework.web.servlet"
to debug level in your preferred logging framework
有什么更好的方式让 Spring 调试日志告诉你自己的顺序。如果您想深入了解代码,您还可以查看org.springframework.web.servlet.FrameworkServlet
( DispatcherServlet
extends 此类) Just enable the logger "org.springframework.web.servlet"
to debug level in your preferred logging framework
Here is how the logs would typically look like - clearly the root context is loaded first and is set as the parent for the context heirarchy - the servlet context is loaded next.
以下是日志通常的样子 - 显然,根上下文首先加载并设置为上下文层次结构的父级 - 接下来加载 servlet 上下文。
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/generalApplicatonContext.xml]
INFO : org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 256 ms
DEBUG: org.springframework.web.servlet.DispatcherServlet - Initializing servlet 'my-servlet'
INFO :Initializing Spring FrameworkServlet 'appServlet'
INFO : org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'my-servlet': initialization started
DEBUG: org.springframework.web.servlet.DispatcherServlet - Servlet with name 'appServlet' will try to create custom WebApplicationContext context of class 'org.springframework.web.context.support.XmlWebApplicationContext', using parent context [Root WebApplicationContext: startup date [Fri May 15 17:08:24 IST 2015]; root of context hierarchy
DEBUG: Loading XML bean definitions from ServletContext resource [/WEB-INF/spring/specificApplicationContext.xml