上一篇我们在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 = falseif (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是第一次过来,默认是falsenewSingleton = 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对应的单例beansingletonObject = 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*/@Overrideprotected 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);}}