【二】Spring创建Bean的流程1-合并BeanDefinition

本文详细探讨了Spring在启动时如何合并BeanDefinition的过程,从创建ApplicationContext到扫描BeanDefinition,再到BeanDefinition的注册和初始化。文章强调了DefaultListableBeanFactory在Spring容器中的重要性,特别是其beanDefinitionMap和beanDefinitionNames属性。文中还介绍了BeanDefinition合并的逻辑,包括检查mergedBeanDefinitions,处理parentBeanDefinition,并通过递归调用来处理多层次的继承关系。最后,文章提到了非抽象、单例且非懒加载Bean的初始化条件,以及对FactoryBean的特殊处理。
摘要由CSDN通过智能技术生成

前言

这篇文章主要讲spring的getBean过程. 前面我们已经扫描好class文件并封装成BeanDefinition了, 现在拿这些beanDefinition来做点什么了!
建议搭配源码食用, 源码版本 Spring Framework 5.3.10

Spring的启动

	//使用配置类来配置spring
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

上面的代码是传统spring项目, 创建一个Spring容器的代码, spring容器以及bean的初始化都在这一行代码完成, 所以是很重要的一行代码.
点进去这个构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
	this();
	register(componentClasses);
	refresh();
}

可以看到这里首先调用了无参的构造方法, 调用无参构造方法时会先调用父类的无参构造方法

	public AnnotationConfigApplicationContext() {
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		// 额外会创建StandardEnvironment
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

上面分别是AnnotationConfigApplicationContext以及它父类GenericApplicationContext的构造方法
可以看出创建了一个scanner(ClassPathBeanDefinitionScanner), 以及一个reader(AnnotatedBeanDefinitionReader)
父类创建了一个DefaultListableBeanFactory对象赋值给beanFactory(bean工厂)属性

细心的小伙伴就会发现ClassPathBeanDefinitionScanner这个类就是上一篇文章中doScan的那个类, 就是负责bean扫描的类. 你可能会想, 是不是扫描bean是不是就是用这里创建出来的scanner进行的. 很遗憾的告诉你, 并不是. 后面Spring启动流程的文章里会详细介绍的了, 这里先留个印象.

讲完了this(), 接下来简单说说register(componentClasses), 这里就是简单的把AppConfig.class这个类解析成BeanDefinition注册进Spring容器里.

这里说的BeanDefinition注册进Spring容器是什么意思, 这里就要说一个Map org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap, 这个Map就是用来存放那些注册的BeanDefinition. 换言之, 注册bean(registerBean)的过程就是把BeanDefinition放入这个Map中, 所以这个Map很重要. 它的Key是Bean的名字.
再来看看这个Map所在的类DefaultListableBeanFactory, 还记得它吗? 刚刚在这个类的父类的无参构造方法里创建的就是这个类的对象, 所以他也是Spring中很重要的一个类.
这个类中还有一个List org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionNames 专门用来存放这些注册的bean的名字的, 同样是在注册bean的时候把bean的名字存入这个list中.(下面讲getBean就会用到这个list)

说完了前面两个, 剩下最后一个refresh(),

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值