前面分析了从缓存中获取bean,那么没有缓存的时候,按照推理,就是应该创建bean了.
Spring中运用了一个重载方法:getSingleton来进行获取的.
分析一下这个方法
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 (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 创建前,把beanName记录下来,记录他的加载状态
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 这个就是FactoryBean的getObject方法获取,
// 而这个getObject是通过lambada表达式创建的,
// 下面会分析
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 把beanName的创建记录抹去
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 更新三个缓存中的beanName数据
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
其实上面去掉一些判断、异常等操作之后剩余的步骤就是:
- 从缓存中尝试获取
- 没有获取到就记录bean当前加载状态
- 调用FactoryBean的getObject方法进行创建对象
- 创建完成把bean的当前加载状态去掉
- 最后把三级缓存重新洗牌
另外说一下singletonObject = singletonFactory.getObject();
这里的getObject()方法的实现是啥呢?那就要看一下这个方法调用的地方传入的ObjectFactory是啥了
getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
上面其实使用了lambda表达式,因为ObjectFactory是一个函数式接口,所以直接创建了.
() -> {
try {
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
相当于:
()->{
getObject(){
try {
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
}
这样调用了singletonFactory.getObject();方法之后就相当于调用了createBean(beanName, mbd, args)方法.