整合spring中bean的描述信息
学校小故事
为了了解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创建