前文介绍,Servlet 容器启动时如果 web.xml 配置了 ContextLoaderListener,则会调用该对象的初始化方法。根据 Java 语法规定,ContextLoaderListener 的父类 ContextLoader 有一段 static 的代码会更早被执行,这段代码配置了 XML 默认使用的 Context 为
org.springframework.web.context.WebApplicationContext = org.springframework.web.context.support.XmlWebApplicationContext 根据该
定义,如果开发人员没有从 web.xml 指定 contextClass 参数,则默认使用 XmlWebApplicationContext 作为 root WebApplicationContext 工具类。 XML 命名空间及 XML 配置文件解析
Spring 采用 XML 命名空间的方式,为框架的扩展提供了极大的方便。 清单 2. XML 配置文件的命名空间定义
xmlns:context=\ xsi:schemaLocation=\ http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd> 清单 2 展示在 XML 配置文件中引入命名空间的配置范例。 图 1. XML 命名空间及其 handler 定义(查看大图) 展开 Spring 的依赖 jar 文件,可以看到 Spring 各个模块对应的 jar 包都包含一个 META-INF 目录,如果使用了命名空间,则该目录包含了 spring.schemas 和 spring.handlers 两个文件,如图 1 所示。然后 Spring 代码通过 Properties 工具类扫描 project 的 classpath 以及其使用的所有依赖包中 META-INF 目录来得到对应参数值供后续使用。 PropertiesLoaderUtils.loadAllProperties(“META-INF/spring.schemas”, this.classLoader); PropertiesLoaderUtils.loadAllProperties(“META-INF/spring.handlers”, this.classLoader); 清单 3. JAXP 方式解析 XML 文件为 Java 对象 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try{ int validationMode = getValidationModeForResource(resource); // 使用 JAXP 方式,将 XML 配置文件解析为 Java 对象。 Document doc = this.documentLoader.loadDocument(inputSource, getEntityResolver(),this.errorHandler, validationMode, isNamespaceAware()); return registerBeanDefinitions(doc, resource); }

