Spring5.x之XmlBeanFactory源码解析-解析自定义标签(四)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hjtlovelife/article/details/89483561

Spring5.x之XmlBeanFactory源码解析-XmlBeanFactory整体概览(一)

Spring5.x之XmlBeanFactory源码解析-解析前准备(二)

Spring5.x之XmlBeanFactory源码解析-解析默认标签(三)

        我们已经完成了分析默认标签的解析与提取过程,再次看下默认标签解析函数的起始函数:
     

BeanDefinitionParserDelegate.parseBeanDefinitionElement解析返回BeanDefinitionHolder实例,如果不为空就对 beanDefinition 进行装饰,那么什么时候会用到呢?当Spring中bean使用的是默认标签配置,但是其中的子元素却使用自定义配置时,便会起作用了 。 之前对bean的解析分为两种类型,一种是默认类型解析,另一种是自定义类型解析 。为什么要在默认类型解析中添加这个方法处理?这里自定义类型并不是以bean的形式出现,之前讲的两种类型不同处理只是针对bean,这个自定义类型其实是属性 。下面进入到BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired方法,可知对bean元素的所有属性所有子元素进行BeanDefinitionParserDelegate.decorateIfRequired方法调用,先获取属性或者元素的命名空间, 以此来判断该元素或者属性是否是自定义标签,如果是根据命名空间找到自定义的NamespaceHandler并调用NamespaceHandler.decorate方法进行解析 。

<bean>
    <customNameSpace:customElement customAttribute="custom"/>
</bean>

        解析也解析完了装饰也装饰完了,对于得到的beanDefinition已经可以满足后续的使用要求了 ,唯一还剩下的工作就是注册了 ,解析的beanDefinition都会被注册到 BeanDefinitionRegistry类型的实例中, 而对于beanDefinition的注册分成了两部分:通过 beanName 的注册以及通过别名的注册 。

自定义标签解析

Spring自定义标签大致需要如下几步:
1、创建需要扩展的组件
2、定义XSD文件描述组件内容
3、创建BeanDefinitionParser实现类,用来解析XSD文件中的定义和组件定义
4、创建NamespaceHandlerSupport实现类,目的是将BeanDefinitionParser实现类注册到Spring容器
5、编写Spring.handlers和Spring.schemas文件

扫描二维码关注公众号,回复: 6426330 查看本文章

进入到DefaultBeanDefinitionDocumentReader.parseBeanDefinitions方法,根据元素的命名空间来判断是否是自定义标签,如果是则调用BeanDefinitionParserDelegate.parseCustomElement方法解析自定义元素

        解析自定义元素进入BeanDefinitionParserDelegate.parseCustomElement方法,在 readerContext 初始化的时候其属性 namespaceHandlerResolver已经被初始化为DefaultNamespaceHandlerResolver实例。解析得到NamespaceHandler后调用parse方法执行自定义解析逻辑。

        DefaultNamespaceHandlerResolver.resolve方法解析给定命名空间对应的NamespaceHandler,先调用DefaultNamespaceHandlerResolver.getHandlerMappings获取所有的自定义命名空间处理器,其实是读取Spring.handlers配置文件并将配置缓存到map中。如果存在则实例化NamespaceHandler并调用NamespaceHandler.init方法,完成自定义NamespaceHandler注册自定义BeanDefinitionParser。

        调用NamespaceHandler.parse方法执行解析逻辑,根据自定义标签元素名字在自定义命名空间处理其中查找是否有注册的BeanDefinitionParser

        调用AbstractBeanDefinitionParser.parse方法解析,首先会调用AbstractSingleBeanDefinitionParser.parseInternal方法

        调用AbstractSingleBeanDefinitionParser.parseInternal方法解析内置属性,例如:parentName、beanClass、scope、lazyInit,会调用AbstractSingleBeanDefinitionParser.parse方法

        进入AbstractSingleBeanDefinitionParser.parse方法,方法权限是protected,默认什么也不做需要用户自定义实现

猜你喜欢

转载自blog.csdn.net/hjtlovelife/article/details/89483561