自定义标签源码分析

相信了解了自定义标签的使用方法后,会对自定义标签实现过程有一个大概思路。无非是根据对应的bean获取对应的命名空间,根据命名空间解析对应的处理器,然后根据用户自定义处理器进行解析。

(1)获取标签的命名空间


这里获取的节点已经加载了一个xml配置,通过这个方法可以获取到标签的命名空间

(2)提取自定义标签处理器

有了命名空间,就可以进行NamespaceHandler的提取了,继续之前的parseCustomElement跟踪,分析NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri),在readerContext初始化的时候其属性namespaceHandlerResolver已经被初始化为了

DefaultNamespaceHandlerResolver的实例,这里调用resolve方法其实调用的是DefaultNamespaceHandlerResolver类的方法。

上面的函数阐述了解析自定义NamespaceHandler的过程,在上一节中写了自定义标签的使用实例。在这里我们可以看到,可以从Spring.handlers里面直接获取对应关系。

public class MyUserNamespaceHandler extends NamespaceHandlerSupport {      
    @Override      
    public void init() {      
        registerBeanDefinitionParser("user",new UserBeanDefinitionParser());      
    }      
}  

当得到自定义命名空间处理后马上执行namespaceHandler.init()来进行自定义BeanDefinitionParser的注册。

注册后,命名空间处理器就可以根据标签的不同来调用不同的解析器来解析。那么,根据上面的函数与之前自定义标签使用,我们基本可以推断getHandlerMappings的主要功能就是读取Spring.handlers配置文件并将配置文件缓存在map中。


借助了工具PropertiesLoaderUtils对属性handlerMappingsLocation进行了配置文件的读取,handlerMappingsLocation被默认初始化为“META-INF/Spring.handlers”。

(3)标签解析

得到解析及要分析的元素后,Spring就可以将解析工作委托给自定义解析器去解析了,在BeanDefinitionParserDelegate的parseCustomElement方法:

return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

以之前提到的示例进行分析,此时的handler已经确实被实例化成为了我们自定义的MyNamespaceHandler了,而MyNamespaceHandler也已经完成了初始化工作,但是在我们实现的自定义命名空间处理中并没有实现parse方法,这个方法是父类中的实现,查看父类NamespaceHandlerSupport中的parse方法


而对于parse方法的处理:


这大部分代码是用来处理将解析后的将AbstractBeanDefinition转换为BeanDefinitionHolder并注册的功能,而真正去做解析的事情委托给了函数parseInternal,

在parseInternal中并不是直接调用自定义的doParse函数,而是进行了一系列的数据准备,包括对beanClass、scope、lazyInit等属性的准备。



上一篇: 自定义标签使用

下一篇: 基于xml的依赖注入(一)

猜你喜欢

转载自blog.csdn.net/m0_37444820/article/details/80792333