1.情景描述
BeanDefinitionParserDelegate只会处理下图所示的命名空间(NAMESPASE)的根元素及其子元素,
那么Spring 对其他命名空间下的标签如何处理?
二、源码分析
BeanDefinitionParserDelegate.parseCustomElement(Element, BeanDefinition)
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));
}
1.首先获取元素所属的命名空间
2.根据命名空间查找相关的处理器(handler)
3.调用相应的handler处理该元素
那么现在的问题就是第二步(如何根据命名空间查找相关的处理器)?
代码中通过readerContext获取NamespaceHandlerResolver,而这个readerContext 是由外部调用者传入的,体统默认提供了一个DefaultNamespaceHandlerResolver,————————–这里我们先不许考虑
那么现在的问题就是DefaultNamespaceHandlerResolver如何根据命名空间查找相应的handler?
1.读取META-INF/spring.handlers下的这个文件映射为map,文件结构及内容如下:
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
2.从map中读取到相应的value ,利用反射创建对象
总结:
1.Spring 包下的META-INF/spring.handlers 用于存储各个namespace与handler的对应关系
2.设计模式就是拆分80% if-else
—————————————————–其他方法介绍——————————————————-
转载自:https://blog.csdn.net/lj1314ailj/article/details/80464560
parseBeanDefinitionElement流程
1.创建beanDefinition
2.meta元素处理
3.Lookup元素处理
4.ReplacedMethod元素处理
5.constructor-arg元素的处理
6.property元素处理
7.Qualifier元素处理
经过对 Spring Bean 定义资源文件转换的 Document 对象中的元素层层解析,Spring IOC 现在已经将XML 形式定义的 Bean 定义资源文件转换为 Spring IOC 所识别的数据结构——BeanDefinition,它是Bean定义资源文件中配置的POJO对象在SpringIOC容器中的映射,我们可以通过AbstractBeanDefinition为入口,看到了 IOC 容器进行索引、查询和操作。
通过 Spring IOC 容器对 Bean 定义资源的解析后,IOC容器大致完成了管理Bean对象的准备工作,即初始化过程,