protected Class<?> determineContextClass(ServletContext servletContext) { String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM); if (contextClassName != null) { try { return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load custom context class [" + contextClassName + "]", ex); } } else { contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName()); try { return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load default context class [" + contextClassName + "]", ex); } } }
注:CONTEXT_CLASS_PARAM的值是contextClass,这个参数在web.xml中可以不配置。
1)web.xml中没有配置CONTEXT_CLASS_PARAM参数,所有这块逻辑是走
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());这块分支。而这句代码目的是要构建 【org.springframework.web.context.support.XmlWebApplicationContext】作为 WebApplicationContext 的实现类。具体配置开源可以看defaultStrategies的实例化赋值代码。
2)后面的内容就过度到XmlWebApplicationContext的创建过程,这必然涉及到如果获取xml的配置路径。
2.1 抽象模板类 AbstractRefreshableConfigApplicationContext::getConfigLocations方法中,有这样的描述 (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
2.2 那重点就是 this.configLocations 的set 过程。
在ContextLoader::configureAndRefreshWebApplicationContext的方法中,我们可以找到这样的代码
wac.setConfigLocation(configLocationParam); 最终从 String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); 这句代码可以得知它的路径来源是 web.xml中的配置
<param-name>contextConfigLocation</param-name>。
大体这样的逻辑,希望可以帮到你。
...