spring中bean的描述信息

本文通过学校小故事解释Spring中BeanDefinition的整合与初始化过程,涉及BeanDefinition信息变动、RootBeanDefinition获取及源码解析。案例展示了如何根据学生家长角色调整Bean配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学校小故事

为了了解spring流程,需要接受、了解、熟悉很多未知的定义,在此使用 学校 作为辅助,帮助我们了解spring。

学校spring
学校管理局spring开发人员
学校信息ApplicationContext
学校人员信息库DefaultListableBeanFactory
人员bean
学校人员信息BeanDefinition
学校人员信息列表BeanFactory中的beanDefinitionMap属性

故事引申<需求出现>

情况1:小赵学生提供的个人信息<最简单版本,小赵无亲戚在校有职位>。

情况2:小赵学生提供的个人信息,小赵学生的爸爸赵同志是在校老师

情况3:小赵学生提供的个人信息,小赵学生的爸爸赵同志是在校老师,小赵学生的爷爷是校长。

在三种情况下,小赵学生实例化时的信息各不相同。

spring中bean的描述信息

在spring启动前或者执行 BeanFactoryPostProcessor后,在BeanFactory的BeanDefinitionMap属性保存了 spring中所有应当初始化的bean信息。

针对 故事引申中的三种情况,在bean实例化之前,需要将父类中的BeanDefinition信息整合到当前类的BeanDefinition信息中,再进行实例化。

BeanDefinition信息变动过程

1、学生/老师提供个人信息。<GenericBeanDefinition信息>
2、实例化前,学校获取当前人员中的所有信息。<RootBeanDefinition信息>

bean初始化前获取RootBeanDefinition信息 业务流程

0、由于RootBeanDefinition信息属于不会轻易变动,选择使用缓存加快业务流程。

1、先从缓存中获取RootBeanDefinition信息,如果缓存中存在直接返回;
当缓存中不存在RootBeanDefinition信息时,执行getMergedLocalBeanDefinition方法获取RootBeanDefinition信息,并添加到缓存中。

2、缓存中的信息可能发生变动<部分spring版本中RootBeanDefinition存在stale属性,标记BeanDefinition信息是否发生变动,待确认>

bean初始化前获取RootBeanDefinition信息 相关源码

获取BeanDefinition信息源方法

AbstractBeanFactory.class......
doGetBean方法中调用 获取BeanDefinition信息源方法
294行:final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
后续执行bean实例化流程<章末有链接>。

getMergedLocalBeanDefinition方法中
// 从BeanFactory的mergedBeanDefinitions属性中获取RootBeanDefinition信息
1208行:RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 如果mbd存在,直接返回即可
1209行:if (mbd != null) return mbd;
// 缓存中不存在RootBeanDefinition信息,调用getMergedBeanDefinition方法获取RootBeanDefinition信息
1212行:return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));

getMergedBeanDefinition方法
// 考虑到可能出现 多线程同时创建bean实例,将方法加锁
1243行:synchronized (this.mergedBeanDefinitions) 
// 如果当前bean不存在父类,直接将 BeanDefinitionMap中的 BeanDefinition选择性转为RootBeanDefinition信息
1253~1260// 如果当前bean存在父类,获取父类的BeanDefinition信息,合并当前类+父类BeanDefinition信息
// 获取父类BeanDefinition信息
1267行:pbd = getMergedBeanDefinition(parentBeanName);
// 合并当前类+父类BeanDefinition信息
1286+1287行:mbd = new RootBeanDefinition(pbd);   mbd.overrideFrom(bd);
// 设置 RootBeanDefinition 的作用域信息
1292行:mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
// 选择性将RootBeanDefinition信息添加到BeanFactory中的 mergedBeanDefinitions属性 缓存中
1306行:this.mergedBeanDefinitions.put(beanName, mbd);
// 返回组装对象
1301行:return mbd;

2、spring中最开始调用getMergedLocalBeanDefinition方法位置
十三太保之五<invokeBeanFactoryPostProcessors方法>

PostProcessorRegistrationDelegate类中的
invokeBeanFactoryPostProcessors方法
86行:beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

DefaultListableBeanFactory类中的
getBeanNamesForType方法
477行:return doGetBeanNamesForType(******);

doGetBeanNamesForType方法中
501行:RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

参考链接

暂时没有bean实例化流程,正在创作中
spring中FactoryBean创建bean实例链接: FactoryBean创建

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值