1. 程式人生 > >DispatcherServlet以servlet名字載入配置檔案並建立spring上下文

DispatcherServlet以servlet名字載入配置檔案並建立spring上下文

接手個新專案,基於springMVC的架構。但在web.xml裡沒有配置DispatcherServlet的初始化引數contextConfigLocation,專案裡有個api-servlet.xml的spring配置檔案,裡面定義的攔截器和bean卻都被建立了。以為是專案底層自定義了一些schema或者程式碼完成了spring容器的載入,但debug後發現並不是。。。

專案web.xml配置如下:

<filter>
  <filter-name>appFilters</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  <init-param>
    <param-name>contextAttribute</param-name>
    <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.api</param-value>
  </init-param>
  <init-param>
    <param-name>targetFilterLifecycle</param-name>
    <param-value>true</param-value>
  </init-param>
  <async-supported>true</async-supported>
</filter>
<filter-mapping>
  <filter-name>appFilters</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<servlet>
  <servlet-name>api</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  <multipart-config>
    <max-file-size>167108864</max-file-size>
    <max-request-size>167108864</max-request-size>
    <file-size-threshold>111204800</file-size-threshold>
  </multipart-config>
</servlet>
<servlet-mapping>
  <servlet-name>api</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

最後開始debug spring容器的載入過程,終於找到了原因。

FrameworkServlet在重新整理ApplicationContext時,如果沒有configLocations引數時,會使用namespace為字首的xml進行容器載入。namespace如果沒有指定,則使用DispatcherServlet的名字+“-servlet”作為namespace名字。同時以DispatcherServlet的名字作為ApplicationContext的ID:id = "org.springframework.web.context.WebApplicationContext:/api"

上下文初始化完成後,會將ApplicationContext放入ServletContext,以DispatcherServlet的名字。

if (this.publishContext) {
   // Publish the context as a servlet context attribute.
   String attrName = getServletContextAttributeName();
   getServletContext().setAttribute(attrName, wac);
}

attrName = "org.springframework.web.servlet.FrameworkServlet.CONTEXT.api"

所以DelegatingFilterProxy指定了引數contextAttribute,使用api為id的上下文,使用預設root的上下文是null。