前言
上一篇文章中提到了DefaultBeanDefinitionDocumentReader类的processBeanDefinition方法,包含了关键步骤:解析元素生成BeanDefinition 和 注册BeanDefinition。

今天重点聊聊这个:BeanDefinition。
1 BeanDefinition是干什么的?
我们直接打开Spring的源码,搜索BeanDefinition,发现它是一个接口:
BeanDefinition接口中包含了xml的bean中,经常使用的一些属性,比如:className、scope、dependsOn、initMethodName、parentName等,对应的setter/getter方法:
为什么要定义这个接口呢?
答:Spring容器在创建和初始化bean,对象之前,需要从xml文件或者注解中,先收集这些bean的属性和依赖关系,这些信息必须要先保存到某个对象中(这个对象是BeanDefinition实现类的对象,不是真正的bean对象),临时存储一下,然后在后面依赖注入的环节,就知道bean和bean之间的依赖关系,知道怎么初始化bean了。
在Spring中定义了很多BeanDefinition的实现类,不同的实现类用途不一样:
如果我们自己设计一个Spring容器,可能也是这样的思路:
- 先把bean的信息从xml中收集到BeanDefinition的实现类中。
- 基于BeanDefinition的实现类创建bean实例。
- 基于BeanDefinition的实现类完成bean实例之间的依赖注入(有循环依赖的情况存在)。
- 初始化bean实例。
2 如何生成BeanDefinition?
下面重点看BeanDefinition是如何生成的。
上面的方法会调用BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法:
主要流程如下:
一个<bean/>标签会对应一个BeanDefinition对象。
该方法会调用parseBeanDefinitionElement方法,真正创建BeanDefinition对象,并且解析一系列参数填充到对象中:
主要流程如下:

其实真正创建BeanDefinition的逻辑是非常简单的,直接new了一个对象:
真正复杂的地方是在前面的各种属性的解析和赋值上。
3 如何注册BeanDefinition?
上面通过解析xml文件生成了很多BeanDefinition对象,下面就需要把BeanDefinition对象注册到Spring容器中,这样Spring容器才能初始化bean。
在BeanDefinitionReaderUtils类的registerBeanDefinition方法很简单,
只有两个流程:

先看看DefaultListableBeanFactory类的registerBeanDefinition方法是如何注册beanName的:
这个方法主要流程如下:
接下来看看SimpleAliasRegistry类的registerAlias方法是如何注册alias别名的:
主要流程如下:
这样就能通过多个不同的alias找到同一个name,再通过name就能找到BeanDefinition。
4 如何修改BeanDefinition?
上面BeanDefinition对象已经注册到Spring容器当中了,接下来,如果想要修改已经注册的BeanDefinition对象该怎么办呢?
refresh方法中通过invokeBeanFactoryPostProcessors方法修改BeanDefinition对象。
经过一系列的调用,最终会到PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法:


流程看起来很长,其实逻辑比较简单
主要是在处理BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。
而BeanDefinitionRegistryPostProcessor本身是一种特殊的BeanFactoryPostProcessor,它也会执行BeanFactoryPostProcessor的逻辑,只是加了一个额外的方法。
ConfigurationClassPostProcessor是最重要的BeanDefinitionRegistryPostProcessor,它负责处理@Configuration注解。
后面有解析@Configuration注解源码的专题,敬请期待。
我们下期再见。