1. Xml命名空间
1.1. XML 命名空间及 XML 配置文件解析
Spring 采用 XML 命名空间的方式,为框架的扩展提供了极大的方便。xml配置文件的命名空间定义如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="samples.spring"></context:component-scan>
</beans>
1.2. 默认命名空间
Spring在解析xml配置文件的的过程如下:
- 根元素是否属于默认命名空间,如果是默认命名空间,跳到第2步,否则跳到第4步。
- 循环根元素的所有子元素,判断其是否是默认命名空间,如果是跳到第3步,否则跳到第4步。
- 调用默认命名空间方法进行BeanDefinition解析。
- 调用自定义Handler进行BeanDefinition解析。
核心代码如下:
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
private BeanDefinitionParserDelegate delegate;
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
}
详细源码解释参考Xml默认命名空间bean元素解析
1.3. 自定义命名空间
如果xml元素并不是默认命名空间元素,如<context:component-scan/>,则会根据命名空间获取其Handler,使用其Handler进行解析。
public class BeanDefinitionParserDelegate {
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
详细信息参考:Xml自定义命名空间bean元素解析