自定义标签使用
自定义标签解析
public BeanDefinition parseCustomElement(Element ele) {
return this.parseCustomElement(ele, (BeanDefinition)null);
}
// containingBd为父类bean,对顶层元素的解析应设置为null
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
// 获取对应的命名空间
String namespaceUri = this.getNamespaceURI(ele);
// 根据命名空间找到对应的NamespaceHandler
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
} else {
// 调用自定义的NamespaceHandler进行解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
思路比较简单,无非是根据对应的bean获取对应的命名空间,根据命名空间解析对应的处理器,然后根据用户自定义的处理器进行解析。
获取标签的命名空间
标签的解析是从命名空间开始的,无论是区分Spring中默认标签和自定义标签,还是区分自定义标签中不同标签的处理器都是以标签所提供的命名空间为基础的。
提取对应元素命名空间是有现成方法的,就不讲解了
提取自定义标签处理器
Spring.handlers文件中配置命名空间与命名空间处理器的映射关系,只有这样,Spring才能根据映射关系找到匹配的处理器。当获取到自定义的NamespaceHandler之后,就可以进行处理器初始化并解析了
标签解析
得到了解析器以及要分析的元素后,Spring就可以将解析工作委托给自定义解析器去解析了。
解析过程中首先是寻找元素对应的解析器,进而调用解析器中的parse方法,parse方法大部分的代码是用来处理将解析后的AbstractBeanDefinition转化为BeanDefinitionHolder并注册的功能,而真正去做解析的事情委托给了函数parseInternal,进行调用了我们自定义的解析函数。
parseInternal并不是直接调用自定义的doParse函数,而是进行了一系列的数据指标,包括对beanClass、scope、等属性的准备