先说结论 :
Root容器的默认配置文件为/WEB-INF/applicationContext.xml
.
Mvc容器的默认配置文件为/WEB-INF/${dispatcherServletName}-servlet.xml
.
结论可能大家都知道, 但为什么这样呢? “知其然, 并知其所以然”, 程序员的基本素质
首先要分清springMVC由两个WebApplicationContext容器.
第一个是ContextLoaderListener配置的父容器, 下文简称Root容器. (如果web.xml中没有配置则没有该容器)
第二个是由DispatcherServlet完成初始化SpringMVC相关的容器, 下文简称Mvc容器.
且Root容器是Mvc容器的Parent, 啥意思? 就是Root容器的bean能被Mvc容器的bean引用, 反之不行.
如果web.xml中没有配置ContextLoaderListener, 则没有该容器.
正常情况下web.xml中会配置contextConfigLocation来指定Root容器的配置文件位置.
其中param-Value可以用*通配符, 如servletContext-*.xml
来配置
也可以用classpath和classpath*来配置(区别是classpath只匹配到第一个)
也可以配置多个指定位置, 可以用逗号, 分号, 以及换行符来隔开, 如context-rpc.xml,context-mq.xml
contextConfigLocation
classpath:service-appcontext.xml
org.springframework.web.context.ContextLoaderListener
但是如果不小心, 忘记配置context-param, 则取默认配置/WEB-INF/applicationContext.xml
. 依据是什么呢?
直接上代码: XmlWebApplicationContext.java
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
String[] arr$ = configLocations;
int len$ = configLocations.length;
for(int i$ = 0; i$ < len$; ++i$) {
String configLocation = arr$[i$];
reader.loadBeanDefinitions(configLocation);
}
}
}
protected String[] getConfigLocations() {
return this.configLocations != null ? this.configLocations : this.getDefaultConfigLocations();
}
protected String[] getDefaultConfigLocations() {
//nameSpace未设置为null
return this.getNamespace() != null ? new String[]{"/WEB-INF/" + this.getNamespace() + ".xml"} : new String[]{"/WEB-INF/applicationContext.xml"};
}
因为此时Root容器的namespace未设置, j即为null, 所以默认位置为/WEB-INF/applicationContext.xml
.
Mvc容器的配置文件由web.xml中DispatcherServlet的init-param确定. 如下:
webServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:web-appcontext.xml
1
如果DispatcherServlet未配置contextConfigLocation, 则默认取/WEB-INF/${dispatcherServletName}-servlet.xml
为什么呢? 因为该容器的类型也是XmlWebApplicationContext, 和Root容器唯一的差别是Mvc容器的namespace不为null, 而是为${dispatcherServletName}-servlet
, 源码在哪里呢?
答案在FrameworkServlet.java(DispatcherServlet的父类)里:
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
wac.setServletContext(this.getServletContext());
wac.setServletConfig(this.getServletConfig());
wac.setNamespace(this.getNamespace());//就是这一行
wac.addApplicationListener(new SourceFilteringListener(wac, new FrameworkServlet.ContextRefreshListener()));
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources(this.getServletContext(), this.getServletConfig());
}
this.postProcessWebApplicationContext(wac);
this.applyInitializers(wac);
wac.refresh();
}
public String getNamespace() {
return this.namespace != null ? this.namespace : this.getServletName() + "-servlet";
}
备注: 以上代码SpringMVC的版本为3.2.16.RELEASE