在创建 bean 的实例对象时,会调用 (org.springframework.beans.factory.support)AbstractBeanFactory#doGetBean:

    1. protected <T> T doGetBean(
    2. String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    3. throws BeansException {
    4. // 获取 bean 名称
    5. String beanName = transformedBeanName(name);
    6. Object beanInstance;
    7. // 从缓存中获取单例的 bean:获取单例对象的时候,会触发三级缓存的处理,原型模式和单例模式最大的区别就是,前者不会放入缓存
    8. // Eagerly check singleton cache for manually registered singletons.
    9. Object sharedInstance = getSingleton(beanName);
    10. // 如果获取到单例 bean(bean != null),则走下面代码
    11. if (sharedInstance != null && args == null) {
    12. if (logger.isTraceEnabled()) {
    13. if (isSingletonCurrentlyInCreation(beanName)) {
    14. logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
    15. "' that is not fully initialized yet - a consequence of a circular reference");
    16. }
    17. else {
    18. logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
    19. }
    20. }
    21. // 如果取出来的 Bean 实例是 FactoryBean 的 Bean 实例,则需要从 FactoryBean 的实例中产生一个对象实例
    22. beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    23. }
    24. else {// 如果没有获取到单例 bean (bean == null),就走下面的代码
    25. // 如果 <原型模式(prototype)> 的 bean 发生循环引用,则直接不处理,抛出异常 (大多数获取都是用的单例模式)
    26. // 原型模式是无法解决循环引用和循环依赖问题的 ...
    27. // Fail if we're already creating this bean instance:
    28. // We're assumably within a circular reference.
    29. if (isPrototypeCurrentlyInCreation(beanName)) {
    30. throw new BeanCurrentlyInCreationException(beanName);
    31. }
    32. // 调用父工厂去找一找这个 bean
    33. // Check if bean definition exists in this factory.
    34. BeanFactory parentBeanFactory = getParentBeanFactory();
    35. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    36. // Not found -> check parent.
    37. String nameToLookup = originalBeanName(name);
    38. if (parentBeanFactory instanceof AbstractBeanFactory) {
    39. return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
    40. nameToLookup, requiredType, args, typeCheckOnly);
    41. }
    42. else if (args != null) {
    43. // Delegation to parent with explicit args.
    44. return (T) parentBeanFactory.getBean(nameToLookup, args);
    45. }
    46. else if (requiredType != null) {
    47. // No args -> delegate to standard getBean method.
    48. return parentBeanFactory.getBean(nameToLookup, requiredType);
    49. }
    50. else {
    51. return (T) parentBeanFactory.getBean(nameToLookup);
    52. }
    53. }
    54. // 类型检查是否唯一
    55. if (!typeCheckOnly) {
    56. markBeanAsCreated(beanName);
    57. }
    58. StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
    59. .tag("beanName", name);
    60. //---------------------------- bean 处理核心 ----------Spring 中一个 try...catch() 基本上就是一个处理核心--------------------------------
    61. try {
    62. if (requiredType != null) {
    63. beanCreation.tag("beanType", requiredType::toString);
    64. }
    65. // 获取要实例化的 bean 的 BeanDefinition 对象
    66. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    67. // 检查该 BeanDefinition 对象对应的 Bean 是否是抽象的
    68. checkMergedBeanDefinition(mbd, beanName, args);
    69. // Guarantee initialization of beans that the current bean depends on.
    70. String[] dependsOn = mbd.getDependsOn();
    71. if (dependsOn != null) {
    72. for (String dep : dependsOn) {
    73. if (isDependent(beanName, dep)) {
    74. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    75. "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
    76. }
    77. registerDependentBean(dep, beanName);
    78. try {
    79. getBean(dep);
    80. }
    81. catch (NoSuchBeanDefinitionException ex) {
    82. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    83. "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    84. }
    85. }
    86. }
    87. // ---------------------------------------- 单例的 Bean---------------------------------------------------------------------------
    88. // Create bean instance.
    89. if (mbd.isSingleton()) {
    90. // 使用 lambuda 表达式来调用 getSingleton 方法获取一个单例对象
    91. // public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) 第二个参数传入一个匿名内部类
    92. sharedInstance = getSingleton(beanName, () -> {
    93. try {
    94. // 创建单例 Bean 的主要方法,创建一个单例 bean
    95. return createBean(beanName, mbd, args);
    96. }
    97. catch (BeansException ex) {
    98. // Explicitly remove instance from singleton cache: It might have been put there
    99. // eagerly by the creation process, to allow for circular reference resolution.
    100. // Also remove any beans that received a temporary reference to the bean.
    101. destroySingleton(beanName);
    102. throw ex;
    103. }
    104. });
    105. beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    106. }
    107. // -----------------------------------------------------------------------------------
    108. // ------------------------- 多例(原型) ----------------------------------------------------
    109. // 多例
    110. else if (mbd.isPrototype()) {
    111. // It's a prototype -> create a new instance.
    112. Object prototypeInstance = null;
    113. try {
    114. beforePrototypeCreation(beanName);
    115. prototypeInstance = createBean(beanName, mbd, args);
    116. }
    117. finally {
    118. afterPrototypeCreation(beanName);
    119. }
    120. beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    121. }
    122. // -----------------------------------------------------------------------------
    123. // 既非单例也非多例,request 或者是 session 级别
    124. else {
    125. String scopeName = mbd.getScope();
    126. if (!StringUtils.hasLength(scopeName)) {
    127. throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
    128. }
    129. Scope scope = this.scopes.get(scopeName);
    130. if (scope == null) {
    131. throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    132. }
    133. try {
    134. Object scopedInstance = scope.get(beanName, () -> {
    135. beforePrototypeCreation(beanName);
    136. try {
    137. return createBean(beanName, mbd, args);
    138. }
    139. finally {
    140. afterPrototypeCreation(beanName);
    141. }
    142. });
    143. beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    144. }
    145. catch (IllegalStateException ex) {
    146. throw new ScopeNotActiveException(beanName, scopeName, ex);
    147. }
    148. }
    149. }
    150. //-------------------------------------------------------------------------------------------------------->
    151. catch (BeansException ex) {
    152. beanCreation.tag("exception", ex.getClass().toString());
    153. beanCreation.tag("message", String.valueOf(ex.getMessage()));
    154. cleanupAfterBeanCreationFailure(beanName);
    155. throw ex;
    156. }
    157. finally {
    158. beanCreation.end();
    159. }
    160. }
    161. return adaptBeanInstance(name, beanInstance, requiredType);
    162. }

    在创建单例对象时,会先后进入两个方法,第一个会进入 (org.springframework.beans.factory.support)DefaultSingletonBeanRegistry#getSingleton:

    1. /**
    2. * 获取单例对象
    3. */
    4. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    5. Assert.notNull(beanName, "Bean name must not be null");
    6. synchronized (this.singletonObjects) {
    7. Object singletonObject = this.singletonObjects.get(beanName);
    8. if (singletonObject == null) {
    9. if (this.singletonsCurrentlyInDestruction) {
    10. throw new BeanCreationNotAllowedException(beanName,
    11. "Singleton bean creation not allowed while singletons of this factory are in destruction " +
    12. "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
    13. }
    14. if (logger.isDebugEnabled()) {
    15. logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
    16. }
    17. // 创建之前,设置一个创建中的标识
    18. beforeSingletonCreation(beanName);
    19. boolean newSingleton = false;
    20. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    21. if (recordSuppressedExceptions) {
    22. this.suppressedExceptions = new LinkedHashSet<>();
    23. }
    24. // ------------------------------- bean 创建流程完成 ---------------------------------------------------------
    25. try {
    26. // 调用匿名内部类获取单例对象
    27. // 该步骤的完成就意味着 bean 的创建流程完成
    28. singletonObject = singletonFactory.getObject();
    29. newSingleton = true;
    30. }
    31. // ----------------------------------------------------------/
    32. catch (IllegalStateException ex) {
    33. // Has the singleton object implicitly appeared in the meantime ->
    34. // if yes, proceed with it since the exception indicates that state.
    35. singletonObject = this.singletonObjects.get(beanName);
    36. if (singletonObject == null) {
    37. throw ex;
    38. }
    39. }
    40. catch (BeanCreationException ex) {
    41. if (recordSuppressedExceptions) {
    42. for (Exception suppressedException : this.suppressedExceptions) {
    43. ex.addRelatedCause(suppressedException);
    44. }
    45. }
    46. throw ex;
    47. }
    48. finally {
    49. if (recordSuppressedExceptions) {
    50. this.suppressedExceptions = null;
    51. }
    52. // 创建成功之后,删除创建中的标识,如果存在这个标识,就说明这个 bean 正在创建中
    53. afterSingletonCreation(beanName);
    54. }
    55. // 将创建的单例 bean 放入缓存中(总共三级缓存)
    56. if (newSingleton) {
    57. addSingleton(beanName, singletonObject);
    58. }
    59. }
    60. return singletonObject;
    61. }
    62. }

    这里的 afterSingletonCreation(beanName) 的作用是根据 bean 创建一个标识,如果在 bean 创建时检测到已经存在 bean 的标识,就说明这个 bean 正在创建中,如果没有标识就说明 bean 已经创建完成;使用这个方法可以解决循环依赖的问题。

    (org.springframework.beans.factory.support)DefaultSingletonBeanRegistry#afterSingletonCreation:

    1. protected void afterSingletonCreation(String beanName) {
    2. if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
    3. throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    4. }
    5. }

    (org.springframework.beans.factory.support)DefaultSingletonBeanRegistry$singletonsCurrentlyInCreation 是一个集合:

    1. /**
    2. * 标记位 可以用这个 set 来判断对象是否在创建中
    3. */
    4. private final Set<String> singletonsCurrentlyInCreation =
    5. Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    此集合可以用来存储 beanName,如果 beanName 在这个集合中,就说明这个 bean 对象正在创建中,如果不在就说明 bean 对象已经创建完成了。

    随后会进入 (org.springframework.beans.factory.support)AbstractAutowireCapableBeanFactory#createBean:

    1. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    2. throws BeanCreationException {
    3. if (logger.isTraceEnabled()) {
    4. logger.trace("Creating instance of bean '" + beanName + "'");
    5. }
    6. RootBeanDefinition mbdToUse = mbd;
    7. // Make sure bean class is actually resolved at this point, and
    8. // clone the bean definition in case of a dynamically resolved Class
    9. // which cannot be stored in the shared merged bean definition.
    10. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    11. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    12. mbdToUse = new RootBeanDefinition(mbd);
    13. mbdToUse.setBeanClass(resolvedClass);
    14. }
    15. // 处理方法覆盖
    16. // Prepare method overrides.
    17. try {
    18. mbdToUse.prepareMethodOverrides();
    19. }
    20. catch (BeanDefinitionValidationException ex) {
    21. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    22. beanName, "Validation of method overrides failed", ex);
    23. }
    24. try {
    25. // 获取 BeanPostProcessor 的代理对象
    26. // InstantiationAwareBeanPostProcessor 接口对 bean 的实例化的干预处理
    27. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    28. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    29. if (bean != null) {
    30. return bean;
    31. }
    32. }
    33. catch (Throwable ex) {
    34. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    35. "BeanPostProcessor before instantiation of bean failed", ex);
    36. }
    37. try {
    38. // 完成 Bean 实例的创建(实例化 填充属性 初始化)
    39. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    40. if (logger.isTraceEnabled()) {
    41. logger.trace("Finished creating instance of bean '" + beanName + "'");
    42. }
    43. return beanInstance;
    44. }
    45. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
    46. // A previously detected exception with proper bean creation context already,
    47. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
    48. throw ex;
    49. }
    50. catch (Throwable ex) {
    51. throw new BeanCreationException(
    52. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    53. }
    54. }

    进入 (org.springframework.beans.factory.support)AbstractAutowireCapableBeanFactory#doCreateBean:

    1. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    2. throws BeanCreationException {
    3. // Instantiate the bean.
    4. // Spring 中 ~Wrapper 都是装饰的意思,是 Spring 装饰模式的表现形式
    5. BeanWrapper instanceWrapper = null;
    6. if (mbd.isSingleton()) {
    7. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    8. }
    9. // ------------------------------- bean 初始化第一步:默认调用无参函数构造实例化 Bean ---------------------------
    10. // 构造参数依赖注入,就是发生在这一步
    11. if (instanceWrapper == null) {
    12. instanceWrapper = createBeanInstance(beanName, mbd, args);
    13. }
    14. // 实例化后的 Bean 对象
    15. Object bean = instanceWrapper.getWrappedInstance();
    16. Class<?> beanType = instanceWrapper.getWrappedClass();
    17. if (beanType != NullBean.class) {
    18. mbd.resolvedTargetType = beanType;
    19. }
    20. // Allow post-processors to modify the merged bean definition.
    21. synchronized (mbd.postProcessingLock) {
    22. if (!mbd.postProcessed) {
    23. try {
    24. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    25. }
    26. catch (Throwable ex) {
    27. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    28. "Post-processing of merged bean definition failed", ex);
    29. }
    30. mbd.postProcessed = true;
    31. }
    32. }
    33. // Eagerly cache singletons to be able to resolve circular references
    34. // even when triggered by lifecycle interfaces like BeanFactoryAware.
    35. // ------------------------- 将第一步创建的对象放入 3 级缓存中 --------------------------------
    36. // 解决循环依赖的关键步骤
    37. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    38. isSingletonCurrentlyInCreation(beanName));
    39. // 如果需要提前保留单例 Bean ,则将该 Bean 放入三级缓存中
    40. if (earlySingletonExposure) {
    41. if (logger.isTraceEnabled()) {
    42. logger.trace("Eagerly caching bean '" + beanName +
    43. "' to allow for resolving potential circular references");
    44. }
    45. // 将刚创建的 bean 放入三级缓存中 singleFactories(key 是 beanName,value 是 FactoryBean)
    46. // 此处使用了一个匿名内部类来表示 ObjectFactory () -> getEarlyBeanReference(beanName, mbd, bean)
    47. // 同时也把第一步创建的 bean 提前封装到了 getEarlyBeanReference 中
    48. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    49. }
    50. // -------------------------------------------------------------------------------/
    51. // Initialize the bean instance.
    52. Object exposedObject = bean;
    53. try {
    54. // ----------------------------------- bean 初始化第二部:填充属性 (DI 依赖注入发生在此步骤) ----------------
    55. // 调用反射和内容去进行属性设置
    56. // 属性值需要进行类型转换
    57. populateBean(beanName, mbd, instanceWrapper);
    58. // ------------------------------------------------/
    59. // ------------------------------------- bean 初始化第三步:调用初始化方法,完成 bean 的初始化操作(AOP 发生在此步骤) ---
    60. exposedObject = initializeBean(beanName, exposedObject, mbd);
    61. // --------------------------------------------------/
    62. }
    63. catch (Throwable ex) {
    64. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    65. throw (BeanCreationException) ex;
    66. }
    67. else {
    68. throw new BeanCreationException(
    69. mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
    70. }
    71. }
    72. if (earlySingletonExposure) {
    73. Object earlySingletonReference = getSingleton(beanName, false);
    74. if (earlySingletonReference != null) {
    75. if (exposedObject == bean) {
    76. exposedObject = earlySingletonReference;
    77. }
    78. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    79. String[] dependentBeans = getDependentBeans(beanName);
    80. Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    81. for (String dependentBean : dependentBeans) {
    82. if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    83. actualDependentBeans.add(dependentBean);
    84. }
    85. }
    86. if (!actualDependentBeans.isEmpty()) {
    87. throw new BeanCurrentlyInCreationException(beanName,
    88. "Bean with name '" + beanName + "' has been injected into other beans [" +
    89. StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    90. "] in its raw version as part of a circular reference, but has eventually been " +
    91. "wrapped. This means that said other beans do not use the final version of the " +
    92. "bean. This is often the result of over-eager type matching - consider using " +
    93. "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
    94. }
    95. }
    96. }
    97. }
    98. // Register bean as disposable.
    99. try {
    100. registerDisposableBeanIfNecessary(beanName, bean, mbd);
    101. }
    102. catch (BeanDefinitionValidationException ex) {
    103. throw new BeanCreationException(
    104. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    105. }
    106. return exposedObject;
    107. }

    此处完成了 bean 创建的三部曲,同时在第一步骤完成时,做了一个解决循环依赖的操作,此处存入缓存的条件是:

    • 对象是否是单例
    • 能不能允许循环引用
    • 依赖 对象是否创建中 (此处就是指的上一步变量 singletonsCurrentlyInCreation)

    如果符合上面的三个条件,就将创建的 bean 对象放入三级缓存中。

    另外,在可以看到解决循环依赖的代码是位于 bean 创建的第一步骤 和 第二步骤之间,也就是位于 bean 实例化 和 bean 属性填充之间:
    image.png

    所以Spring 通过三级缓存来解决循环依赖,且只能解决Set 方法循环依赖,因为循环依赖解决操作是在对象创建之后才进行的。如果是构造方法循环依赖,是无法解决的,只能修改。