Spring 源码阅读 11:BeanDefinition 介绍

BeanDefinition 加载过程总结

  • 在准备阶段,Spring 根据 XML 配置文件的路径,创建 Resource 对象,提供了对配置资源文件的访问。然后,再使用 EncodedResource 对资源进行封装,以添加编码和字符集特性。再之后,会将资源的输入流封装成用于 XML 解析的 InputSource 对象。

  • 在资源加载阶段,Spring 的主要工作是把上一步得到的 InputSource 和资源对象本身,交给 XML 解析器进行解析,并最终得到 Document 对象。在解析之前,Spring 准备了一些要提供给解析器的配置信息,包括自定义的 EntityReslver、错误处理逻辑、XML 文件验证模式等。

  • 在 BeanDefinition 解析的阶段,Spring 会把上一步加载资源得到的 Document 对象,解析成 BeanDefinition 对象。首先,会创建一个 BeanDefinitionDocumentReader 对象,并将解析任务交给这个对象。然后,BeanDefinitionDocumentReader 会创建一个 BeanDefinitionParserDelegate 对象,最终将解析的具体任务交给了 BeanDefinitionParserDelegate。解析工作的主要逻辑就是创建一个 GenericBeanDefinition 对象,并将通过 Document 对象获取到 XML 文件中配置的所有内容,为 GenericBeanDefinition 相应的属性赋值。

  • 最后就是注册 BeanDefinition 的阶段,在得到 BeanDefinition 之后,要将其注册到 Spring 的容器,也就是 BeanFactory 中。注册之前,Spring 还会对解析到的 BeanDefinition 进行检查,确保没有相互冲突的配置。确保没有问题后,将 BeanDefinition 添加到真正的容器 beanDefinitionMap 中,它是一个 ConcurrentHashMap 类型的集合。最后还会对 BeanDefinition 的别名进行检查,确保他们之间不会发生冲突和混淆。

BeanDefinition 类关系介绍

分析了这么多流程,还没有单独介绍 BeanDefinition。它是 Spring 框架中最重要的接口之一,用来表示 Spring 容器中 Bean 的定义,Spring 容器中的 Bean 都是根据 BeanDefinition 来创建的。

以下是 BeanDefinition 相关的接口和类的关系图:

之前分析的 BeanDefinition 加载流程中,创建的都是 GenericBeanDefinition 类型的 BeanDefinition。在比较早的版本中,Spring 都是使用 RootBeanDefinition 和 ChildBeanDefinition,它们分别用来创建没有parent属性和有parent属性的 Bean,在 Spring 的 2.5 版本之后,开始使用 GenericBeanDefinition,如果需要声明 BeanDefinition 之间的父子关系,可以通过setParentName方法来设置。这三个实现类表示的都是从 XML 配置中解析到的 BeanDefinition,在图中可以看到,GenericBeanDefinition、RootBeanDefinition、ChildBeanDefinition 都直接继承了 AbstractBeanDefinition。

除此之外,还有 AnnotatedGenericBeanDefinition 和 ScannedGenericBeanDefinition 两个类继承了 GenericBeanDefinition,从名字可以看出,他们表示的是通过注解和组件扫描得到的 BeanDefinition。

由此可见,在这个体系中,除了 BeanDefinition 接口之外,AbstractBeanDefinition 也是一个很重要的类,它是所有 BeanDefinition 实现类的父类。

AbstractBeanDefinition 抽象类

在 BeanDefinition 接口中,定义的都是大量属性相关的 getter 和 setter 方法,因此,我们重点看一下 AbstractBeanDefinition 中都包含哪些内容。

在 AbstractBeanDefinition 中也有大量的方法定义,不过基本也都是 getter 和 setter 方法,毕竟 BeanDefinition 表示类定义,也就是需要保存大量的实例化 Bean 的信息,比如 XML 文件中的配置信息,它的主要作用其实就是保存数据,因此,在 AbstractBeanDefinition 中声明了大量的公共属性,他们都对应着 XML 配置文件中bean标签的属性和子标签信息。

在 BeanDefinitionParserDelegate 的parseBeanDefinitionAttributes方法中也可以看出,从bean标签的属性中出来的内容也都保存在了这些属性中。

总结

本文总结了 BeanDefinition 加载的过程,并对 BeanDefinition 接口下重要的类作了介绍。BeanDefinition 中的涉及到属的性非常多,在之后的源码分析中,还会遇到,到时候再进行详细探索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值