前言

在 finishBeanFactoryInitialization 中介绍了创建 Bean 的流程大概流程,这里进入单例 Bean 的创建过程。
16-Spring 单例 Bean 的创建 - 图1
这里主要分为三个部分创建单例 Bean

  1. getSingleton
  2. createBean
  3. getObjectForBeanInstance

下面进入源码:

getSingleton

  1. public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
  2. Assert.notNull(beanName, "Bean name must not be null");
  3. // 加锁
  4. synchronized (this.singletonObjects) {
  5. // 检查 singletonObjects 缓存中是否有
  6. Object singletonObject = this.singletonObjects.get(beanName);
  7. if (singletonObject == null) {
  8. // 检查是否在执行销毁
  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. // 将 Bean 添加到 singletonsCurrentlyInCreation 集合中, 表示正在创建
  18. beforeSingletonCreation(beanName);
  19. boolean newSingleton = false;
  20. boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
  21. if (recordSuppressedExceptions) {
  22. this.suppressedExceptions = new LinkedHashSet<>();
  23. }
  24. try {
  25. // 调用工厂方法
  26. // 也就是调用 createBean(beanName, mbd, args)
  27. singletonObject = singletonFactory.getObject();
  28. newSingleton = true;
  29. }
  30. catch (IllegalStateException ex) {
  31. // Has the singleton object implicitly appeared in the meantime ->
  32. // if yes, proceed with it since the exception indicates that state.
  33. singletonObject = this.singletonObjects.get(beanName);
  34. if (singletonObject == null) {
  35. throw ex;
  36. }
  37. }
  38. catch (BeanCreationException ex) {
  39. if (recordSuppressedExceptions) {
  40. for (Exception suppressedException : this.suppressedExceptions) {
  41. ex.addRelatedCause(suppressedException);
  42. }
  43. }
  44. throw ex;
  45. }
  46. finally {
  47. if (recordSuppressedExceptions) {
  48. this.suppressedExceptions = null;
  49. }
  50. // 创建成功, 从 singletonsCurrentlyInCreation 移除
  51. afterSingletonCreation(beanName);
  52. }
  53. if (newSingleton) {
  54. // 将给定的单例对象添加到该工厂的单例缓存中
  55. // this.singletonObjects.put(beanName, singletonObject);
  56. // this.singletonFactories.remove(beanName);
  57. // this.earlySingletonObjects.remove(beanName);
  58. // this.registeredSingletons.add(beanName);
  59. addSingleton(beanName, singletonObject);
  60. }
  61. }
  62. return singletonObject;
  63. }
  64. }

返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个新对象。
这一块一共可以拆成三部分来理解:
16-Spring 单例 Bean 的创建 - 图2

1. 从缓存中获取 singletonObjects

singletonObject 是什么?

  1. /** Cache of singleton objects: bean name to bean instance. */
  2. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

singletonObjects 是一个 ConcurrentHashMap, 用来缓存单例对象的实例。

2. 创建 singletonObject

在从缓存中没有获取到 singletonObject ,创建新的对象
singletonObject = singletonFactory.getObject();
这一步其实就是调用外边的 createBean(beanName, mbd, args) 方法,这是一个工厂方法。 通过 createBean 方法,会创建一个新的 singletonObject

3. 将创建的 singletonObject 添加到缓存中

  1. protected void addSingleton(String beanName, Object singletonObject) {
  2. synchronized (this.singletonObjects) {
  3. this.singletonObjects.put(beanName, singletonObject);
  4. this.singletonFactories.remove(beanName);
  5. this.earlySingletonObjects.remove(beanName);
  6. // 已经成功创建的单例
  7. this.registeredSingletons.add(beanName);
  8. }
  9. }

这一步涉及到三个缓存,以及一个成功创建的单例列表。

  1. /** Cache of singleton objects: bean name to bean instance. */
  2. /** 缓存单例对象, K-V -> BeanName - Bean 实例 */
  3. private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  4. /** Cache of singleton factories: bean name to ObjectFactory. */
  5. /** 缓存 Bean 工厂 */
  6. private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  7. /** Cache of early singleton objects: bean name to bean instance. */
  8. /** 缓存早期单例对象 */
  9. private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
  10. /** Set of registered singletons, containing the bean names in registration order. */
  11. /** 已注册的单例列表,按注册顺序保存 BeanName。 */
  12. private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

将创建的单例对象,添加到单例缓存中,同时将工厂缓存以及早期单例对象缓存中的对应对象删除。

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. // 获取真实的类型
  11. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  12. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  13. // 创建新的 mbd 防止 其他线程修改
  14. mbdToUse = new RootBeanDefinition(mbd);
  15. mbdToUse.setBeanClass(resolvedClass);
  16. }
  17. // Prepare method overrides.
  18. try {
  19. // 验证并准备为此bean定义的方法替代。 检查是否存在具有指定名称的方法。
  20. mbdToUse.prepareMethodOverrides();
  21. }
  22. catch (BeanDefinitionValidationException ex) {
  23. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  24. beanName, "Validation of method overrides failed", ex);
  25. }
  26. try {
  27. // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
  28. // 应用实例化之前的后处理器,以解决指定的bean是否存在实例化快捷方式。
  29. // InstantiationAwareBeanPostProcessor 后置处理器
  30. // postProcessBeforeInstantiation 方法可能会已经实例化 Bean
  31. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  32. if (bean != null) {
  33. return bean;
  34. }
  35. }
  36. catch (Throwable ex) {
  37. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  38. "BeanPostProcessor before instantiation of bean failed", ex);
  39. }
  40. try {
  41. // 实例化 Bean
  42. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  43. if (logger.isTraceEnabled()) {
  44. logger.trace("Finished creating instance of bean '" + beanName + "'");
  45. }
  46. return beanInstance;
  47. }
  48. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  49. // A previously detected exception with proper bean creation context already,
  50. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  51. throw ex;
  52. }
  53. catch (Throwable ex) {
  54. throw new BeanCreationException(
  55. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  56. }
  57. }

这个方法中涉及到:创建 Bean 实例 , 填充 Bean , 应用 PostProcessor。
其中实例化 Bean 是在 doCreateBean 中。现在重点看一下 doCreateBean 方法。

doCreateBean

  1. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.
  4. // Bean 的 对象包装
  5. BeanWrapper instanceWrapper = null;
  6. if (mbd.isSingleton()) {
  7. // 从缓存中获取
  8. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  9. }
  10. if (instanceWrapper == null) {
  11. // 缓存中获取不到则直接创建, 这里创建的 BeanInstance !!!
  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. // 如果允许修改 mbd
  25. // 调用 MergedBeanDefinitionPostProcessor 后置处理器的
  26. // postProcessMergedBeanDefinition(mbd, beanType, beanName);
  27. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  28. }
  29. catch (Throwable ex) {
  30. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  31. "Post-processing of merged bean definition failed", ex);
  32. }
  33. mbd.postProcessed = true;
  34. }
  35. }
  36. // Eagerly cache singletons to be able to resolve circular references
  37. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  38. // mbd 是单例 且 允许循环引用, (默认 true) 且在创建
  39. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  40. isSingletonCurrentlyInCreation(beanName));
  41. if (earlySingletonExposure) {
  42. if (logger.isTraceEnabled()) {
  43. logger.trace("Eagerly caching bean '" + beanName +
  44. "' to allow for resolving potential circular references");
  45. }
  46. // 先获取 之前的 Bean 的引用, 从 beanPostProcessorCache 中 获取 SmartInstantiationAwareBeanPostProcessor
  47. // 然后从 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 获取之前的引用
  48. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  49. }
  50. // Initialize the bean instance.
  51. Object exposedObject = bean;
  52. try {
  53. // 属性赋值
  54. populateBean(beanName, mbd, instanceWrapper);
  55. // 执行 init 方法
  56. exposedObject = initializeBean(beanName, exposedObject, mbd);
  57. }
  58. catch (Throwable ex) {
  59. if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
  60. throw (BeanCreationException) ex;
  61. }
  62. else {
  63. throw new BeanCreationException(
  64. mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
  65. }
  66. }
  67. // 这里允许循环依赖
  68. if (earlySingletonExposure) {
  69. // 获取早期的 Bean, 如果没有循环依赖 则获取不到
  70. Object earlySingletonReference = getSingleton(beanName, false);
  71. // 有循环依赖
  72. if (earlySingletonReference != null) {
  73. // 创建的是不是同一个,可能会有代理对象
  74. if (exposedObject == bean) {
  75. exposedObject = earlySingletonReference;
  76. }
  77. else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
  78. // 获取依赖的 Bean 并 循环放入到 actualDependentBeans
  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. // 注册销毁方法
  101. registerDisposableBeanIfNecessary(beanName, bean, mbd);
  102. }
  103. catch (BeanDefinitionValidationException ex) {
  104. throw new BeanCreationException(
  105. mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
  106. }
  107. return exposedObject;
  108. }

同样是代码很长很长!
分步骤阅读:
16-Spring 单例 Bean 的创建 - 图3
如果这个 Bean 是单例 Bean 且允许循环引用且在创建中,则说明在有循环引用。则调用:
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这一行代码涉及到两个方法,分别是 getEarlyBeanReferenceaddSingletonFactory

  • getEarlyBeanReference

16-Spring 单例 Bean 的创建 - 图4

  • addSingletonFactory

16-Spring 单例 Bean 的创建 - 图5
这一块可以看到将创建的一个单例对象的 singletonFactory 添加到了 singletonFactories 缓存中。
同时将 earlySingletonObjects 缓存中的单例对象移除。
那什么时候添加到 earlySingletonObjects 缓存中的呢?
这块可以参考 Spring 源码学习 15:finishBeanFactoryInitializationgetSingleton 方法中 put 进去的。
为了方便,我把这一小块代码也贴出来:
16-Spring 单例 Bean 的创建 - 图6
在这里将缓存从 singletonFactories 移到了 earlySingletonObjects
Spring 的 Bean 实例化的时候用到的三级缓存其实是:
singletonObjects: 一级缓存,存储单例对象,Bean 已经实例化,初始化完成。
earlySingletonObjects: 二级缓存,存储 singletonObject,这个 Bean 实例化了,还没有初始化。
singletonFactories: 三级缓存,存储 singletonFactory
下面会初始化 Bean
这里关注重点关注下面一部分:
16-Spring 单例 Bean 的创建 - 图7

  • populateBean

对 Bean 的属性进行赋值。
这块需要注意的是,在对属性进行赋值时,发现依赖了其他 Bean,就会去先创建其他 Bean。
我这边使用的注解 _@_Autowired 就会执行下面一部分:
16-Spring 单例 Bean 的创建 - 图8
在这里解析属性的时候,就会去创建内部依赖的 Bean。