前言

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

image

今天重点聊聊这个:BeanDefinition。

1 BeanDefinition是干什么的?

我们直接打开Spring的源码,搜索BeanDefinition,发现它是一个接口:imageBeanDefinition接口中包含了xml的bean中,经常使用的一些属性,比如:className、scope、dependsOn、initMethodName、parentName等,对应的setter/getter方法:image为什么要定义这个接口呢?

答:Spring容器在创建和初始化bean,对象之前,需要从xml文件或者注解中,先收集这些bean的属性和依赖关系,这些信息必须要先保存到某个对象中(这个对象是BeanDefinition实现类的对象,不是真正的bean对象),临时存储一下,然后在后面依赖注入的环节,就知道bean和bean之间的依赖关系,知道怎么初始化bean了。

在Spring中定义了很多BeanDefinition的实现类,不同的实现类用途不一样:image

如果我们自己设计一个Spring容器,可能也是这样的思路:

  1. 先把bean的信息从xml中收集到BeanDefinition的实现类中。
  2. 基于BeanDefinition的实现类创建bean实例。
  3. 基于BeanDefinition的实现类完成bean实例之间的依赖注入(有循环依赖的情况存在)。
  4. 初始化bean实例。

2 如何生成BeanDefinition?

下面重点看BeanDefinition是如何生成的。

上面的方法会调用BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法:image主要流程如下:image

一个<bean/>标签会对应一个BeanDefinition对象。

该方法会调用parseBeanDefinitionElement方法,真正创建BeanDefinition对象,并且解析一系列参数填充到对象中:image主要流程如下:

image

其实真正创建BeanDefinition的逻辑是非常简单的,直接new了一个对象:image真正复杂的地方是在前面的各种属性的解析和赋值上。

3 如何注册BeanDefinition?

上面通过解析xml文件生成了很多BeanDefinition对象,下面就需要把BeanDefinition对象注册到Spring容器中,这样Spring容器才能初始化bean。

在BeanDefinitionReaderUtils类的registerBeanDefinition方法很简单,image只有两个流程:

image

先看看DefaultListableBeanFactory类的registerBeanDefinition方法是如何注册beanName的:image这个方法主要流程如下:image

接下来看看SimpleAliasRegistry类的registerAlias方法是如何注册alias别名的:image主要流程如下:image

这样就能通过多个不同的alias找到同一个name,再通过name就能找到BeanDefinition。

4 如何修改BeanDefinition?

上面BeanDefinition对象已经注册到Spring容器当中了,接下来,如果想要修改已经注册的BeanDefinition对象该怎么办呢?

refresh方法中通过invokeBeanFactoryPostProcessors方法修改BeanDefinition对象。

经过一系列的调用,最终会到PostProcessorRegistrationDelegate类的invokeBeanFactoryPostProcessors方法:imageimageimageimage流程看起来很长,其实逻辑比较简单image主要是在处理BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。

而BeanDefinitionRegistryPostProcessor本身是一种特殊的BeanFactoryPostProcessor,它也会执行BeanFactoryPostProcessor的逻辑,只是加了一个额外的方法。imageConfigurationClassPostProcessor是最重要的BeanDefinitionRegistryPostProcessor,它负责处理@Configuration注解。

后面有解析@Configuration注解源码的专题,敬请期待。

我们下期再见。

最后修改:2026 年 06 月 05 日
如果觉得我的文章对你有用,请随意赞赏