bean标签的解析及注册(二)解析BeanDefinition

本文深入解析Spring框架中bean标签的解析过程,特别是BeanDefinition的创建及其与<bean>标签属性的对应关系。文章详细介绍了如何通过BeanDefinition将配置信息转换为内存数据库,并讲解了构造函数参数的解析,包括如何处理不同类型的构造函数参数,如value、map等。通过阅读源码,作者鼓励读者理解Spring内部工作原理,以提升Java技术水平。
摘要由CSDN通过智能技术生成

下面从元素解析及信息提取开始,也就是:

1,

2,

3,

我们进一步看步骤AbstractBeanDefinition beanDefinition=parseBeanDefinitionElement(ele,beanName,containingBean)中,对其他属性的解析过程,(我想再次重申一次,查看Spring源码是一个艰苦且枯燥的过程,如果能坚持下来,你会发现收获巨大。

1,创建用于承载属性的BeanDefinition

BeanDefinition是一个接口,在Spring中存在三种实现:RootBeanDefinition,ChildBeanDefinition,以及GenericBeanDefinition.三种实现均继承了AbstractBeanDefinition,其中BeanDefinition是配置文件<bean>元素标签在容器中的内如表现形式。<bean>元素标签拥有class,scope,lazy-init等配置属性,BeanDefinition则提供了相应的beanClass,scope,lazeInit属性,BeanDefinition和<bean>属性是一一对应的。其中RootBeanDefinition是最常用的实现类,它对应一般的<bean>元素标签,GenericBeanDefinition是自2.5版本以后新加入的bean文件配置属性定义类,是一站式服务类。

在配置文件中可以定义父<bean>和字<bean>,父<bean>用RootBeanDefinition表示,而子<bean>用ChildBeanDefinition表示,而没有父<bean>的<bean>就使用RootBeanDefinition表示。AbstractBeanDefinition对两者共同的类信息进行抽象。

Spring通过BeanDefinition将配置文件中的<bean>配置信息转换为容器的内部表示,并将浙西BeanDefinition注册到BeanDefinitionRegistry中。Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存,后续操作直接从BeanDefinitionResistry中读取配置信息。它们之间的关系如下图所示:

因此,要解析属性首先要创建用于承载属性的实例,也就是创建GenericBeanDefinition类型的实例。而代码createBeanDefinition(className,parent)的作用就是实现此功能。

1).下面说下子元素constructor-arg的解析

对构造函数的解析式非常常用,也是非常复杂的,下面举个构造函数的小例子

<beans>

      <!-- 默认情况是按照参数的顺序注入,当指定index索引后就可以改变注入参数的顺序 -->

      <bean id= "helloBean" class="com.HelloBean">

              <constructor-arg index="0">

                       <value>刘哲</value>

              </cibstructor-arg>

              <constructor-arg index="1">

                       <value>你好</value>

              </cibstructor-arg>

      </bean>

</beans>

对于constructor-arg子元素的解析,Spring是通过parseConstructorArgElements函数来实现的,具体的代码如下:

这个结构中遍历所有子元素,也就是提取所有constructor-arg,然后进行解析,具体的解析被放置在了另个函数parseConstructorArgElement中,

可以看到对于是否定义index属性,Spring的处理是不同的,关键在于属性信息被保存的位置。

了解整个流程后,继续尝试了解解析构造函数配置中子元素的过程,进入parsePropertyValue:


最后设计到了对子元素的处理,例如下面:

<constructor-arg>

       <map>

               <entry key="key" value='value'/>

      </map>

</constructor-arg>

在这里处理map是怎么实现的呢,parsePropertySubElement中实现了对各种子元素的分类处理。

上面的函数中已经理清了所有可支持子类的分类处理。

在下一节中我们将具体分析都是那么属性配置到了GenericBeanDefiniton中,会比较轻松些,这些源码阅读起来会比较累,但还是希望愿意看的人坚持下来,因为看完这些你会发现自己进入了另一片天地,是java提高必不可少 的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值