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


问题内容

假设我有一个 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>

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

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

注意:
是否对多个servlet映射使用多个spring配置是一个好习惯,这值得商bat。使用XML配置而不是新的Java配置也是如此。但这不是我要在这里问的。让我们尝试着眼于我的主要问题。


问题答案:

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实际上是上面加载的子上下文,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>

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