上一篇我们在Spring源码十八:Bean实例化流程一 中,主要讨论了Spring在实例化前的两重要准备工作,1、获取我们前面注册好的BeanDefinition,将GenericBeanDefinition封装为RootBeanDefinition如果Bean Definition只存在父容器中,还会进行合并操作,然后做了严谨的异常判断处理。2、如果bean配置了依赖的bean的名称,还会检查下配置的依赖,是否已经处于bean依赖的引用链上了,如果没有处于bean依赖引用链上,就会提前来实例化bean依赖的那些bean。最后找到实例化的入口。
今天我们开始分析下单例bean是如何创建:咱们接着上一篇代码往下看
getSingleton
再进入代码中看下逻辑:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 从单例缓存中获取Bean的实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 如果当前bean正在销毁标志为true,则抛出异常。 默认:singletonsCurrentlyInDestruction = false
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放入singletonsCurrentlyInCreation列表中,标志当前bean正在被创建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// !!!! 调用简单工厂方法来实例化bean !!!! //
singletonObject = singletonFactory.getObject();
// 标志当前bean是第一次过来,默认是false
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// 再努力一次,如果通过简单工厂创建失败: 尝试从单例缓存中,获取beanName对应的单例bean
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;
}
// 从singletonsCurrentlyInCreation列表中移出,标志当前beanName对应的bean已经创建完成了。
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 看到了嘛,看到了嘛,第一次标志在这里用的,单例缓存入的地方也再这里,哈哈 我们找到啦
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
这段代码是Spring框架中用于创建和获取单例bean实例的一部分。以下是对这段代码的分析:
-
使用lambda表达式:代码中使用了Java 8的lambda表达式来创建一个匿名的
ObjectFactory
实例。这个ObjectFactory
会在需要时调用其getObject()
方法来创建bean。 -
getSingleton()方法:
getSingleton(beanName, singletonFactory)
方法被调用来获取名为beanName
的单例bean。如果这个bean尚未被创建,singletonFactory.getObject()
将被调用以创建它。 -
createBean()方法:在lambda表达式中,如果bean不存在,将调用
createBean(beanName, mbd, args)
方法来创建bean。这个方法负责完整的bean创建过程,包括依赖注入、初始化等步骤。 -
异常处理:如果在创建bean的过程中抛出了
BeansException
(例如,由于循环依赖或其他bean创建问题),代码将执行以下操作:- 调用
destroySingleton(beanName)
来从单例缓存中移除部分创建的bean实例。这是必要的,因为创建过程中可能会因为解决循环依赖而提前将bean放入缓存。 - 抛出原始的
BeansException
,以通知调用者bean创建失败。
- 调用
-
获取bean实例:如果bean成功创建,
sharedInstance
将包含新创建的bean实例。然后,调用getObjectForBeanInstance(sharedInstance, name, beanName, mbd)
方法来获取bean实例对象。这个方法可能执行额外的处理,比如应用FactoryBean
的逻辑或处理bean的后置处理(post-processing)。 -
单例缓存:整个过程中,Spring使用
singletonObjects
作为缓存来存储已经创建的单例bean。这样,后续请求相同bean时可以直接从缓存中获取,而不需要重新创建。
这段代码体现了Spring框架中创建单例bean的复杂性,包括异常安全、延迟初始化和对循环依赖的处理。通过使用 ObjectFactory
和lambda表达式,Spring能够以一种灵活且高效的方式来管理bean的生命周期。
createBean
上面我已经找到真正创建bean的地方,也看到Spring是通过简单工厂创建实例的也验证了人命常说的bean工厂、工厂模式。同时也看到单例bean首次创建,会放入单例缓存池中。但是整个方法有个内部类,当然这里是Java8的函数式接口实现的,咱们跳出来看下这个默认方法是做了什么逻辑处理。通过这个方法来
看到上图标注的地方createBean见名知意,应该是这个方法包含了实例化的核心逻辑,咱们进入方法内部一探究竟之前简单分析一下:在这个内部类里首先会通过createBean来实例化一个bena,如果实例化的过程中出现了异常,就会调用方法destroy Singleton方法,来清除单利bean相关的一系列缓存信息。
/**
* Central method of this class: creates a bean instance, 创建bean实例对象
* populates the bean instance, applies post-processors, etc. 填充bean实例、应用后置处理器
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition. 判断需要创建的bean是否可以实例化、是否可以通过当前类加载器加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides. 准备bean中的方法覆盖
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 给BeanPostProcessors一个返回代理而不是目标bean实例的机会。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 如果bean配置类后置处理器PostProcessor,则这里返回一个proxy代理对象
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args); // bean实例对象创建方法
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}