Spring Framework的核心 - IOC容器的实现 - BeanDefinition

1. 概述

在之前的文章中有提到过,SpringIOC容器管理了我们定义的各种Bean对象及其相互的关系,Bean对象在Spring实现中是以BeanDefinition来描述的;

BeanDefinition也叫spring bean的建模对象,也就是把可以表示bean的模型对象;

在学习JVM虚拟机的时候,了解到普通类的实例化过程是先将java文件编译成class文件,继而java虚拟机启动会把这些class文件load到内存,当遇到new关键字的时候会根据类的模板信息实例化这个对象也就是在堆上面分配内存
在这里插入图片描述
但是对于Spring来说实例化一个bean的过程更为复杂,因为它涉及到bean的一些配置,如懒加载的,作用域等信息,Class无法完成对带有这些额外信息的bean的抽象,故而需要一个BeanDefinition类来抽象这些信息,以便于spring能够完美的实例化一个bean

2. springbean实例化过程

记录一下子路老师的spring源码系列(三)——beanDefinition(1)

在这里插入图片描述
假设在你的项目或者磁盘上有X和Y两个类,X是被加了spring注解的,Y没有加spring的注解;也就是正常情况下当spring容器启动之后通过getBean(X)能正常返回Xbean,但是如果getBean(Y)则会出异常,因为Y不能被spring容器扫描到不能被正常实例化;

① 当spring容器启动的时候会去调用ConfigurationClassPostProcessor这个bean工厂的后置处理器完成扫描,也就是把类的信息读取到,比如类的类型(class),比如类的名字,类的构造方法,scopelazydependsOn等等信息

② 当spring读取到类的信息之后会实例化一个BeanDefinition的对象,继而调用这个对象的各种set方法存储信息;每扫描到一个符合规则的类,spring都会实例化一个BeanDefinition对象,然后把根据类的类名生成一个bean的名字(比如一个类IndexServicespring会根据类名IndexService生成一个bean的名字indexServicespring内部有一套默认的名字生成规则,但是程序员可以提供自己的名字生成器覆盖spring内置的)

③ 继而spring会把这个beanDefinition对象和生成的beanName放到一个map当中,key=beanName,value=beanDefinition对象,这个map专门用来存beanDefinition

走到这一步,就可以使用得到的beanDefinition生成想要的对象了,Spring也为我们提供了另一条路,也就是BeanFactoryPostProcessor,后置处理器,它能够在应用程序上下文的标准初始化之后修改它的内部bean工厂,是spring提供的一个扩展点

④当spring把类所对应的beanDefintion对象存到map之后,spring会调用程序员提供的bean工厂后置处理器,在应用程序上下文的标准初始化之后修改它的内部bean工厂

3. BeanFactoryPostProcessor后置处理器

BeanFactoryPostProcessor可以在应用程序上下文的标准初始化之后修改它的内部bean工厂,是spring提供的一个扩展点(spring提供很多扩展点,学习spring源码的一个非常重要的原因就是要学会这些扩展点,以便对spring做二次开发或者写出优雅的插件),可以让程序员干预bean工厂的初始化过程,比如给beanFactory中新增bean,修改bean

@Component
public class TestBeanFactoryPostPorcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		//转换为子类,因为父类没有添加beanDefintion对象的api
		DefaultListableBeanFactory defaultbf =
				(DefaultListableBeanFactory) beanFactory;

		//new一个Y的beanDefinition对象,方便测试动态添加
		GenericBeanDefinition y= new GenericBeanDefinition();
		y.setBeanClass(Y.class);
		//添加一个beanDefinition对象,原本这个Y没有被spring扫描到
		defaultbf.registerBeanDefinition("y", y);

		//得到一个已经被扫描出来的beanDefintion对象x
		//因为X本来就被扫描出来了,所以是直接从map中获取
		BeanDefinition x = defaultbf.getBeanDefinition("x");
		//修改这个X的beanDefintion对象的class为Z
		//原本这个x代表的class为X.class;现在为Z.class
		x.setBeanClassName("com.luban.beanDefinition.Z");
	}
	
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值