接手个新项目,基于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。