在Spring Servlet项目的web.xml中加载contextConfigLocation的顺序

假设我有一个Spring Java项目,我正在尝试将其配置为Web服务器servlet。 这是web.xml文件的精简版本:

 contextConfigLocation  /WEB-INF/spring/generalApplicationContext.xml    my-servlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/specificApplicationContext.xml  1   my-servlet /foo/*  

这里需要注意的关键是我已经指定了两个要加载的XML文件。 一个是我的整个应用程序的通用,而另一个是特定于“my-servlet”servlet。 对于只有一个servlet映射的设置,这没有意义。 但是,我的项目有多个servlet映射,每个都有特定的Spring设置。

我的问题: Spring将首先加载哪个contextConfigLocation? 它是generalApplicationContext.xml还是specialApplicationContext.xml? 更重要的是,装载的顺序是否重要? 从我的调试工作来看,它似乎很明显,因为当我将一些独立的Spring配置从一个文件移动到另一个文件时,我得到了不同的错误。

注意:对于多个servlet映射是否使用多个弹簧配置是一个好的做法是值得商榷的。 使用XML配置而不是新的Java配置也是如此。 但这不是我在这里要问的问题。 让我们试着关注我的主要问题。

generalApplicationContext.xml是首先加载的,因为它是使用ContextLoaderListener加载的ApplicationContext

  org.springframework.web.context.ContextLoaderListener   contextConfigLocation  /WEB-INF/spring/generalApplicationContext.xml   

specificApplicationContext.xml实际上是上面加载的generalApplicationContext.xml的子上下文,它将是一个WebApplicationContext

  my-servlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/specificApplicationContext.xml  1   my-servlet /foo/*  

是的,加载顺序很重要。 因为在加载父上下文时,必须满足所有必需的依赖项。

下面的部分加载上下文文件并创建ApplicationContext 。 例如,此上下文可能包含组件,例如中间层事务服务,数据访问对象或您可能希望在整个应用程序中使用(和重用)的其他对象。 每个应用程序将有一个应用程序上下文。

  contextConfigLocation  /WEB-INF/spring/generalApplicationContext.xml   

另一个上下文是WebApplicationContext ,它是应用程序上下文子上下文 。 Spring Web应用程序中定义的每个DispatcherServlet都将具有关联的WebApplicationContextWebApplicationContext的初始化发生如下:

  my-servlet org.springframework.web.servlet.DispatcherServlet  contextConfigLocation /WEB-INF/spring/specificApplicationContext.xml  1  

有关详细信息,请参阅此和此

实际拥有Spring调试日志的更好方法是告诉您自己的顺序。 如果你想进入代码,你也可以看一下org.springframework.web.servlet.FrameworkServletDispatcherServlet扩展这个类)只需启用logger "org.springframework.web.servlet"来调试你喜欢的级别记录框架

以下是日志通常的样子 – 显然首先加载根上下文并将其设置为上下文层次结构的父上下文 – 接下来加载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 

如果您在web.xml中使用ContextLoaderListener ,则spring将首先加载generalApplicationContext.xml 。 这将创建bean并为它们提供所有Servlet和filter。 这个xml应该有你的应用程序中使用的公共类bean。

后来的spring容器将加载specificApplicationContext.xml ,因为你在servlet配置中启动时加载了。 如果未在启动时指定负载,则在第一个请求带有特定url-pattern的应用程序时,将加载此specificApplicationContext.xml

当您将springconfig从一个配置移动到另一个配置时,这是您的问题,这将更改容器的应用程序资源可用性。 如果在generalApplicationContext.xml中指定Controller bean,并且未在specificApplicationContext.xml中指定它们,则DispatcherServlet将找不到映射,因此您将看到404错误。

如果要按需创建一些bean对象,可以再创建一个servlet-config来加载特定的specificConfigurationFile2.xml,并映射到url-pattern。