spring中的三个缓存
singletonObjects, earlySingletonObjects, singletonFactories
- 调用getBean方法是访问缓存的顺序:singletonObjects, earlySingletonObjects, singletonFactories
- 访问缓存的条件:
- singletonObjects(始终允许访问)
- earlySingletonObjects(singletonObjects返回null 且bean正在创建)
- singletonFactories(earlySingletonObjects返回null 且允许循环依赖)
- 把一个bean放入缓存的先后顺序:singletonFactories、earlySingletonObjects、singletonObjects
创建bean的几个阶段
- 1、先从缓存中获取bean返回null。
getSingleton(beanName);
- 2、标记为正在创建的bean。
markBeanAsCreated(beanName);
- 3、准备创建bean。
拉姆达 -> return createBean(beanName, mbd, args);
- 4、创建半成品bean。
AbstractAutowireCapableBeanFactory#doCreateBean
- 5、把半成品bean封装为
ObjectFactory<?>
并存放到singletonFactories
缓存中 - 6、开始填充属性。
populateBean(beanName, mbd, instanceWrapper);
- 7、初始化。
exposedObject = initializeBean(beanName, exposedObject, mbd);
- 8、比对bean、重新赋值
- 9、返回bean,放入
singletonObjects
循环依赖
循环依赖发生在属性填充 6-阶段
。A和B相互依赖且先创建A,看看循环依赖是如何产生的
A进行属性填充之前已经把半成品放入了singletonFactories
中,进入第6阶段:
- A填充B属性时发现
singletonObjects
没有B。(不具备访问其他两个map的条件) - 需要重新创建B,创建B需要走上面的几个阶段
入栈······
- B也创建半成品,缓存办成品到
singletonFactories
中 - B也开始填充属性···
- B填充A
singletonObjects
中没有A,但是A正在创建且允许循环引用,最终在singletonFactories
中发现了A。 - B开始调用
singletonFactories
创建A的完整对象并放入earlySingletonObjects
中 - 把A填充到B的属性中,至此B创建完成,
出栈······
- B创建完给A的属性赋值
继续第七阶段: - 半成品初始化(很重要…)
- 比对(
半成品初始化后A
的和earlySingletonObjects中的A
比对)
Java不是引用传递吗?对象应该都是同一个啊?为什么要比对?
答案是:半成品对象和代理对象不是同一个对象
spring创建代理对象的时机
属性填充后的初始化阶段
如果一个类没有循环引用且这个类需要创建代理对象,那么这个类的代理对象会在这个阶段创建。也就是这个方法AbstractAutowireCapableBeanFactory#initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 就是这里调用后置处理器
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
// 就是这个后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
// earlyProxyReferences如果存在就不创建代理对象了???很重要
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 开始创建代理对象
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
循环依赖阶段
// earlyProxyReferences如果存在就不创建代理对象了???很重要
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 开始创建代理对象
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
cacheKey
是哪个方法往这个earlyProxyReferences
中put的?
// 创建bean的第五个阶段(填充属性之前,循环依赖之前)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
// 循环依赖阶段
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
singletonFactory.getObject();
// put阶段
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
代码
// 入口
================AbstractBeanFactory.doGetBean=================
{
// DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>)
sharedInstance = getSingleton(beanName, () -> {
try {
// AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])
return createBean(beanName, mbd, args);
});
}
}
========= DefaultSingletonBeanRegistry.getSingleton(λ工厂) ===========
{
//访问单例缓存,返回空
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject ==null) {
beforeSingletonCreation(beanName); // 标记为正在创建
singletonObject = singletonFactory.getObject(); // 调用λ工厂
return singletonObject;
}
//循环依赖解决完成之后才会执行这里。
afterSingletonCreation(beanName);
addSingleton(beanName, singletonObject);
}
================= λ 中的createBean=======
================= 即singletonFactory.getObject()=================
================= 即AbstractAutowireCapableBeanFactory.doCreateBean =================
{
Object beanInstance = doCreateBean(beanName, mbdToUse, args) {
// 半成品wrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 获取半成品
final Object bean = instanceWrapper.getWrappedInstance();
// === 封装为factory返回缓存起来===
// 条件this.allowCircularReferences默认值是true,填充属性阶段这个值为false
// 从用户getBean开始这个值一直是默认值true,直到填充属性时spring源码调用getBean(beanName,false)
// 这个false就是不允许循环引用了
(mbd.isSingleton()&& this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)) {
// 缓存半成品,循环依赖就是借助这个factory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)) {
synchronized (this.singletonObjects)
if (!this.singletonObjects.containsKey(beanName)){
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
// 暴露bean
Object exposedObject = bean;
//属性填充(允许循环依赖,下面接着创建依赖的bean)
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 属性填充就是后置处理器的事情了(为属性创建实例、属性循环依赖、使用singletonFactories缓存解决依赖、等等)
// 下面就不允许循环依赖了(至此singletonFactories缓存的使用已经完成了)
}
// 比较阶段:() -> getEarlyBeanReference(beanName, mbd, bean);
// 这个拉姆达表达式的功劳,第三个参数:拉姆达持有bean,会对这个bean进一步加工(循环依赖阶段:otherBean -> factory.getObject(bean))
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
{
// 理解
simpleBean { // 同一个simpleBean对象(引用相同)
1、singletonFactories(simpleBean) 先放入factory
2、填充属性(simpleBean) ===> 获取factory进一步加工 ===> 结果就是 simpleBean变成enhancedBean,一个新的代理对象地址不一样
earlySingletonObjects.put(enhancedBean)
3、init(simpleBean)
// 比较阶段
simpleBean已经过时了,重新赋值 simpleBean = enhancedBean
返回simpleBean。
exposedObject == simpleBean
earlySingletonReference == enhancedBean
把这个方法看会 AbstractAutowireCapableBeanFactory.doCreateBean 循环引用也就理解的差不多了
循环引用至此完结!
}
}
========= 三个缓存
// 访问单例缓存
singletonObject = singletonObjects.get(beanName);
// 访问factory.getObject()返回对象的缓存
if(singletonObject== null && 正在创建){
singletonObject = earlySingletonObjects.get(beanName);
if(singletonObject == null && 允许循环引用阶段){
// 访问factory缓存、继续创建对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory!=null){
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject); I
this.singletonFactories.remove(beanName);
}
=========== A<=>B相互依赖
=========== A<=>B相互依赖
-- singletonFactories: 存放办成品的A, 然后创建B。B又依赖A,从factory中取出A继续创建A。把A放到earlySingletonObjects中
-- earlySingletonObjects:factory继续加工的bean
-- singletonObjects:B创建完成之后继续A的流程,这个流程流程就是对比阶段。
对比阶段把最终的bean放进singletonObjects,aka:factory继续加工的bean