Spring源码浅析之BeanDefinition

我们在Spring源码中可以看到其是通过AbstractAutowireCapableBeanFactory这个类完成对bean的创建的。在以后的博客中,我会再详细介绍Spring是如何创建一个bean的。
在这之前,我们需要对一些其他类有一个先入的了解,其中,在创建bean时反复出现的RootBeanDefinition类就是必须要先了解的类之一。
RootBeanDefinition类其实是AbstractBeanDefinition的一个子类。AbstractBeanDefinition实现了BeanDefinition接口。
Spring通过BeanDefinition接口,将配置文件或配置文件中的<bean>或@Configuration和@Bean修饰的配置类的配置信息转换为Spring容器的内部表示,并将这些BeanDefiniton注册到BeanDefinitonRegistry中。
下面我们就从AbstractBeanDefinition类开始,看看Spring中的BeanDefinition。

AbstractBeanDefinition
AbstractBeanDefinition这个抽象类有着承上启下的重要性。我们可以从它的类图中可以看出:
这里写图片描述
它是RootBeanDefinition,GenericBeanDefinition和ChildBeanDefinition这三个类的父类,同时它继承自BeanMetadataAttributeAccessor这个类,并实现了BeanDefinition这个接口,还提供了深度拷贝其他BeanDefinition类中配置的方法和默认配置bean的方法等实用方法。

BeanMetadataAttributeAccessor
BeanMetadataAttributeAccessor这个类能够对bean的配置源及其属性进行读写,用于跟踪配置源,从它的类方法中也能看出:
这里写图片描述

BeanDefinition
BeanDefinition接口描述了一个bean的配置信息,对应xml配置或Java注解配置中对bean的配置,它有以下几个方法:
这里写图片描述
它包含了诸如bean的scope、是否懒加载、是否为单例等重要的配置信息。这些接口方法都在AbstractBeanDefinition类中实现。

RootBeanDefinition
适用于有根/子关系的配置源,与ChildBeanDefinition相对应,不存在父节点,对应xml配置中的<bean>的根标签。提供了一系列重载的构造方法和便捷方法,例如获取bean的类型,各种参数的缓存等。

ChildBeanDefinition
适用于有根/子关系的配置源,与RootBeanDefinition相对应,存在父节点。对应xml配置中的<bean>的子标签。

ConfigurationClassBeanDefinition
ConfigurationClassBeanDefinitionReader的内部类,继承自RootBeanDefinition。
ConfigurationClassBeanDefinitionReader这个类用于读取配置文件中的bean配置信息,并加载至BeanDefinitionRegistry中。
这里写图片描述
其中,loadBeanDefinitionsForConfigurationClass作为私有的入口方法,配合其他方法实现从ConfigurationClass类中读取BeanDefinition信息并注册至BeanDefinitionRegistry中,一个ConfigurationClass类代表用@Configuration注解修饰的类,以及该类中用@Bean注解修饰的方法。
为了与其他配置源(如xml配置文件)作区分,ConfigurationClassBeanDefinitionReader这个类专门通过ConfigurationClassBeanDefinition类,读取并创建ConfigurationClass类的配置信息。

GenericBeanDefinition
自2.5以后新加入的bean文件配置属性定义类,是一站式服务类,可以说是RootBeanDefinition和ChildBeanDefinition的一般替代品。适用于一般情况下,用户自己配置的bean的属性定义。
它还有两个子类AnnotatedGenericBeanDefinition类和ScannedGenericBeanDefinition类,常用于测试代码,用来读取AnnotatedBeanDefinition类的注解元数据信息。
其中ScannedGenericBeanDefinition类基于ASM ClassReader,与AnnotatedGenericBeanDefinition不同,用于能够被Spring容器扫描到的类(例如被@Component注解的类),而AnnotatedGenericBeanDefinition只能用于已经被注册或被扫描到的类。

总结
BeanDefinition是Spring容器对一个bean的配置(定义)的基本描述。Spring容器通过各种BeanDefinition的实现类对不同配置源的bean的配置信息进行注册与管理。可以说BeanDefinition是bean在Spring容器中的表示形式。

猜你喜欢

转载自blog.csdn.net/ljw761123096/article/details/80353202