前面一篇文章中讲解了从缓存中加载bean,如果缓存中不存在已经加载的单例bean,就需要实现bean的加载过程。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
//首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用已创建的bean,所以这一步是必须的。
Object singletonObject = this.singletonObjects.get(beanName);
//如果为空才可以进行singleton的bean的初始化
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while the 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 {
//初始化bean
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 != NULL_OBJECT ? singletonObject : null;
}
}
上述代码中使用了回调方法,使得程序可以在单例创建的前后做一些准备以及处理操作,而真正的获取单例bean的方法其实并不是再次方法中实现的,他的实现逻辑是在ObjectFactory类型的实例singletonFactory中实现的。
(1)检查缓存是否已经加载过
(2)若没有加载,则记录beanName的正在加载状态
(3)加载单例前记录加载状态
beforeSingletonCreation()方法记录加载状态,通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中,这样便可以对循环依赖进行检测。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
(4)通过调用参数传入的ObjectFactory的个体Object方法实例化bean.
(5)加载单例后的处理方法调用
同步骤(3)的记录加载状态相似,当bean加载结束后需要移除缓存中对bean的正在加载状态的记录。
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
(6)将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
protected void addSingleton(String beanName, Object singletonObject) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject != null ? singletonObject : NULL_OBJECT);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
(7)返回结果
虽然我们已经从外部加载了bean的逻辑架构,但现在我们还没有开始对bean加载功能的探索,之前提到过,bean的加载逻辑其实是在传入的ObjectFactory类型的参数singletonFactory中定义的。
参考:《spring源码深度解析》
网友评论