Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析

文章目录

  • Pre
  • Spring处理bdmap 的理念
  • 源码分析
    • Step1 : `this();` 【初始化BeanFactory】
    • register(componentClasses); 【注册bean】
    • refresh();

在这里插入图片描述


Pre

接上文 Spring5源码 - 02 Bean和Java对象的区别与猜想验证BeanDefinition

我们分析了流程, 也从理论上描述了 普通对象 ----- BeanDefinition ------Bean对象之间的关联,提到了一个BeanDefinition的Map集合 (我们称之为 bdmap ,后面都用这个简称代替 ),

那从源码里面怎么体现出来bdmap 的呢?

本篇博文将带你一一掀开


Spring处理bdmap 的理念

因为这个bdmap 对应Spring太重要了,不仅要处理用户配置的扫描包下的bean,还有一点更重要Spring内置的bean 也需要依靠这个bdmap .
如果这个bdmap 完全交给开发者来处理,比如你把这个map中的数据给remove掉了,等等之类的不可信任的操作,结果可想而知,所以Spring封装了一些API,仅允许开发者通过Spring提供的API来修改bdmap .


源码分析

那我们来看下Spring是如何来封装的这个API呢?

接上文中的 BeanFactoryPostProcessor Bean工厂后置处理器

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第1张图片

ConfigurableListableBeanFactory 这个 beanFactory对象 是Spring封装的用于提供给开发者修改BeanDefinition的一个接口类。

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第2张图片

提供了 getBeanDefinition 方法

beanFactory.getBeanDefinition("artisan1");

ctrl + alt + b 打开实现类 DefaultListableBeanFactory

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第3张图片

我们来看下 定义 beanDefinitionMap

	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

Spring也是用的Map来存储的 ~


那我要看 spring是如何把BeanDefinition放到这个 beanDefinitionMap 中的,那我就需要重点观察 beanDefinitionMap 这个对象,Spring是在什么时候赋值的 .

我们知道了 DefaultListableBeanFactory 有个属性 是 beanDefinitionMap

先找DefaultListableBeanFactory

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

看下AnnotationConfigApplicationContetxt的类关系

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第4张图片

跟进去构造函数

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
     
		this();
		register(componentClasses);
		refresh();
	}

Step1 : this(); 【初始化BeanFactory】

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第5张图片

没有呢?我们知道实例化子类,父类也会被初始化,那往上找找吧

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第6张图片

可以看到是在父类GenericApplicationContext中初始化的DefaultListableBeanFactory

这样的话,我们把断点打在下面一行 register(componentClasses)上,观察this 中的对象 如下

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第7张图片

现在是有默认的Spring初始化的时候自己的BeanDefinition , 没有我们自己的bd ,那就继续走,看看这个beanDefinitionMap什么时候会发生变化~


register(componentClasses); 【注册bean】

先看结论

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第8张图片

说明这一步就完成了 从 普通对象 ------- BeanDefinition ----------存入到 bdMap中的操作


接下来分析下核心源码

流程如下
Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第9张图片

如上 ,这个流程完成后, DefaultListableBeanFactory#beanDefinitionMap 就有了new AnnotationConfigApplicationContext(AppConfig.class)

入参中的 AppConfig.class 对应的Bean了

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第10张图片


refresh();

那这个AppConfig配置的扫描包下的bean,什么时候初始化呢? 那就是refresh这个方法了 ,下文继续

先看一眼,结论

Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析_第11张图片

这个方法太重要了,一共有12个方法里面, 下篇博文 继续 分析


你可能感兴趣的:(【spring5.x,源码分析】,BeanDefinition,spring)