

Spring 源码学习 05:BeanDefinition 概念及其实现
source link: https://xie.infoq.cn/article/dc9755019dd8291cba5347215
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言
BeanDefinition:顾名思义,就是 Bean 的定义,是用来描述一个 Bean 都有什么信息。前面说在初始化 DefaultListableBeanFactory
时,会初始化一个 Map<String, BeanDefinition>
,这个 Map 的功能暂且不说,(PS:查资料说的是存储 bean),所以今天就结合官方文档以及源码,一起了解一下 BeanDefinition
!
概念
在容器内部,使用 BeanDefinition
对象定义一个 Bean。而定义的信息包含 类名、作用域、是否懒加载、构造参数、初始化方法、销毁方式等等。
了解了概念之后,开始阅读源码,源码部分比较长。
源码介绍
通过 UML 可以看出 BeanDefinition 接口继承了 AttributeAccessor 和 BeanMetadataElement 两个接口。
AttributeAccessor
AttributeAccessor:定义用于将元数据附加到任意对象或从任意对象访问元数据的通用协定的接口。
publicinterfaceAttributeAccessor{ voidsetAttribute(String name,@NullableObject value); @Nullable ObjectgetAttribute(String name); @Nullable ObjectremoveAttribute(String name); booleanhasAttribute(String name); String[] attributeNames(); }
通过接口方法可以看出,AttributeAccessor 主要定义了对元数据 属性
的增删改查。
AttributeAccessorSupport
是 AttributeAccessor 接口的一个实现,通过实现可以看出,其内部使用了 Map 保存名称和属性值。
BeanMetadataElement
BeanMetadataElement:由包含配置源对象的 bean 元数据元素实现的接口。
publicinterfaceBeanMetadataElement{ @Nullable defaultObjectgetSource(){ returnnull; } }
接口内部只有一个 getSource()
方法,其含义为: 返回此元数据元素的配置源Object (可以为null )。
其实还是不知道啥意思……
在子类( BeanMetadataAttributeAccessor
)中加上断点,debug
这里 source 里面存储了 Class 类文件在磁盘的真实路径。当然姑且可以这么认为,毕竟我这也是刚开始学习源码,当前的结论只是 debug 到的,也有可能在别的实现类中存储的是别的信息。
BeanDefinition
BeanDefinition 方法较多,就不贴代码,或者截图了。详细可以通过 我的 GitHub 进行阅读,上面添加了相关注释。
不过还是简要介绍一下方法,大概有 Bean 的名字、作用范围、是否首选、以及 Bean 的初始化销毁方法等等。
BeanDefinition 只是一个接口,其实现又分为好几种。
AbstractBeanDefinition
AbstractBeanDefinition 作为 BeanDefinition 的抽象实现类,内部定义了很多属性,以满足 BeanDefinition 定义的接口功能。
这些属性的操作,就对应着 BeanDefinition 定义的接口方法。
AbstractBeanDefinition 的三个实现类
AbstractBeanDefinition 的实现又分为三个:分别是 ChildBeanDefinition
、 RootBeanDefinition
、 GenericBeanDefinition
。
-
ChildBeanDefinition:可以从 Parent Definition 里面继承一些公共定义(初始化方法、销毁方法、是否懒加载等等)不过
-
RootBeanDefinition:定义 Bean Definition 的公共属性,该定义在运行时支持Spring BeanFactory中的特定bean。 而 RootBeanDefinition 是不可以设置 parentName 指定 Parent Definition 的。
-
GenericBeanDefinition:是一个通用的 Bean Definition,是一站式服务,用于标准bean定义。 像任何bean定义一样,它允许指定一个类以及可选的构造函数参数值和属性值。 另外,可以通过
parentName
属性灵活地配置从父bean定义派生的内容。所以现在一般使用 GenericBeanDefinition。
从 Spring 2.5 开始,以编程方式注册 Bean Definition 的首选方法是 GenericBeanDefinition 类,该类允许通过 GenericBeanDefinition.setParentName 方法动态定义父依赖项。
GenericBeanDefinition 下面还有两个实现: ScannedGenericBeanDefinition
、 AnnotatedGenericBeanDefinition
。
二者并无太大区别,只不过 AnnotatedGenericBeanDefinition
比 ScannedGenericBeanDefinition
多了一个 factoryMethodMetadata
的定义。
总结
通过阅读 BeanDefinition 的源码,并对其实现类的源码进行阅读之后,大致了解 BeanDefinition 的概念及其含义。大概作图总结如下:
相关推荐
Recommend
-
39
前面提到AbstractRefreshableApplicationContext在刷新BeanFactory时,会调用loadBeanDefinitions方法以加载系统中Bean的定义,下面将讲解Bean定义的加载过程。 一.XML定义 XML配置的加载由AbstractXmlApplication...
-
37
接口表示一种能力,实现了一个接口,即拥有一种能力。 BeanDefinition与Bean的关系, 就好比类与对象的关系. 类在spring的数据结构就是BeanDefinition.根据BeanDefinition得到的对象就是我们需要的Bean. 我认为理解Bean...
-
8
本文主要分析 spring 中 BeanDefinition 的加载,对于其解析我们在后面的文章中专门分析。 BeanDe...
-
24
一直听说spring对java进行了重定义,设计和封装体系比较宏大;加上最近遇到了spring的问题,为了更好地定位问题,最近一段啃了一下spring源码。我用的源码版本是5.2.28,下面就把最近的研究成果做一下分享...
-
8
深入剖析 Spring 核心数据结构:BeanDefinition 2020-06-21 ...
-
8
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Sprin...
-
3
BeanDefiniton的介绍Spring容器的启动过程大致可以分为两步:BeanDefinition 的加载。容器的初始化。我们知道使用Spring之前我们需要先定义Bean, 一般有两种方式定义,分别是xml和注解,两种方式的大同小异,都需要...
-
8
一、 Spring系统架构 1.1 系统架构图 Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基。 Spring Framework的发展也经历了很多版本的变更,每个版本都有相应的调整
-
4
本文旨在为读者解析Spring源码中的关键类,以便读者在深入阅读源码时,能够了解关键类的作用和用途。在阅读Spring源码时,经常会遇到一些不熟悉的概念,了解关键类的作用可以帮助读者更好地理解这些概念。 BeanDefinition BeanD...
-
3
聚沙成塔!不知不觉 Spring 源码已经连续更了两个月啦,视频也录制了不少了,对 Spring 源码分析感兴趣的小伙伴戳这里哦Spring源码应该怎么学?~ 今天我们继续来看 Sprin...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK