目录
三个缓存都存在于DefaultSingletonBeanRegistry中。以AbstractBeanFactory中的getBean作为入口。
添加到一级缓存的时机
一级缓存主要用于存储单例模式下创建完毕的Bean实例,包括该Bean的实例化,依赖注入,初始化等都完成的一个完整的Bean。
所以添加到一级缓存中的时机:自然是完成Bean的实例化,依赖注入,初始化等操作,生成完整的单例Bean后进行添加的。
源码位置:getBean方法——doGetBean方法——getSingleton创建单例Bean——addSingleton方法
doGetBean方法中创建单例Bean的代码
可以看到,getSingleton方法的入参传入是ObjectFactory类型,使用匿名内部类的方式,传入一个实现了ObjectFactory类的getObject方法的对象,getObject方法通过调用createBean方法完成对象的创建。
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法源码
1、该方法使用synchronized对一级缓存进行加锁。
2、获取到锁后从一级缓存中取Bean对象,取到则直接返回
3、缓存中取不到,则调用ObjectFactory的getObject方法创建对象
4、最后调用addSingleton方法,把单例Bean添加到缓存中
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized(this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
addSingleton方法源码
1、该方法使用synchronized对一级缓存进行加锁。获取singletonObjects锁
2、调用put方法添加到一级缓存
3、清理三级缓存singletonFactories中的该Bean
4、清理二级缓存earlySingletonObjects中的该Bean
5、把该Bean添加到成功列表中,registeredSingletons记录已经创建成功的单例名称。
protected void addSingleton(String beanName, Object singletonObject) {
synchronized(this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
添加到二级缓存的时机
源码位置:getBean方法——doGetBean方法——getSingleton方法
doGetBean中首次调用getSingleton
getSingleton(beanName)此方法先从一级和二级缓存中取,如果都取不到,允许从三级缓存中取,如果从三级缓存中取到Bean。
如果从三级缓存中取到对应的Bean,则把Bean添加到二级缓存,并在三级缓存中清除
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized(this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 添加到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 在三级缓存中清除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
添加到三级缓存的时机
调用createBeanInstance进行Bean实例化之后,调用populateBean进行依赖注入之前
源码位置:getBean方法——doGetBean方法——addSingletonFactory方法
doGetBean方法调用addSingletonFactory方法的源码
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
addSingletonFactory方法源码
1、获取锁
2、添加到三级缓存
3、从二级缓存中进行清理
4、把该Bean添加到成功列表中,registeredSingletons记录已经创建成功的单例名称。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized(this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
总结
添加到一级缓存:完成Bean的实例化,依赖注入,初始化等操作,生成完整的单例Bean后进行添加。
添加到二级缓存:通过getBean获取实例,在三级缓存中获取到时,添加到二级缓存,并清理三级缓存。
添加到三级缓存:通过createBeanInstance实例化Bean之后,调用populateBean进行依赖注入之前。