上一篇我们在Spring源码十八:Bean实例化流程一 中,主要讨论了Spring在实例化前的两重要准备工作,1、获取我们前面注册好的BeanDefinition,将GenericBeanDefinition封装为RootBeanDefinition如果Bean Definition只存在父容器中,还会进行合并操作,然后做了严谨的异常判断处理。2、如果bean配置了依赖的bean的名称,还会检查下配置的依赖,是否已经处于bean依赖的引用链上了,如果没有处于bean依赖引用链上,就会提前来实例化bean依赖的那些bean。最后找到实例化的入口。
今天我们开始分析下单例bean是如何创建:咱们接着上一篇代码往下看

再进入代码中看下逻辑:
- 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的生命周期。
上面我已经找到真正创建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);
- }
- }
