前言

可以说前面的都是准备工作,而接下来开始的才是重点,在这一步会完成 BeanFactory 的初始化,同时实例化单例 Bean。
具体怎么操作的,那就一起阅读源码吧!
不过在阅读源码之前,还是需要了解一些知识的。

  1. 什么是 FactoryBean ?
  2. FactoryBean 是如何使用的 ?
  3. Bean 是如何初始化的?
  4. 常说的循环依赖是怎么解决的?

    什么是 FactoryBean ?

    在官网的这篇文章《What’s a FactoryBean?》中有相关解答,有兴趣的小伙伴可以看一下。
    由内部使用的对象实现的接口,这些对象 BeanFactory 本身就是单个对象的工厂。如果 bean 实现此接口,则它将用作对象公开的工厂,而不是直接用作将自身公开的 bean 实例。
    注意:实现此接口的 bean 不能用作普通 bean。 FactoryBean以 bean 样式定义,但是为 bean 引用(getObject())公开的对象始终是它创建的对象。
    FactoryBeans 可以支持单例和原型,并且可以按需延迟创建对象,也可以在启动时急于创建对象。
    当生命一个 FactoryBean 时,会存在两个类型的 Bean,分别是 FactoryBean 本身,以及它需要创建的类型的 Bean。
    下面是使用示例:

    使用

    1. PaidComponent

    1. public class PaidComponent {
    2. public PaidComponent() {
    3. System.out.println("PaidComponent 无参构造被调用");
    4. }
    5. }

    2. PaidComponentFactoryBean

    ```java @Component public class PaidComponentFactoryBean implements FactoryBean { @Override public PaidComponent getObject() throws Exception {
    1. System.out.println("PaidComponentFactoryBean 的 getObject 方法被调用");
    2. return new PaidComponent();
    } @Override public Class<?> getObjectType() {
    1. return PaidComponent.class;
    }

}

  1. <a name="wFvOa"></a>
  2. #### 3 Test
  3. ```java
  4. public class AnnotationConfigApplicationTest {
  5. public static void main(String[] args) {
  6. AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  7. context.register(JavaConfig.class);
  8. context.refresh();
  9. System.out.println(context.getBean("paidComponentFactoryBean"));
  10. System.out.println(context.getBean("&paidComponentFactoryBean"));
  11. System.out.println(context.getBean(PaidComponent.class));
  12. }
  13. }

15-Spring finishBeanFactoryInitialization - 图1
可以看出注册了两个 Bean, 一个是 paidComponentFactoryBean ,另一个是 &paidComponentFactoryBean
而直接获取 paidComponentFactoryBean 获取到的其实是 FactoryBean 的 getObject() 方法返回的类型。

finishBeanFactoryInitialization 源码

  1. protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
  2. // Initialize conversion service for this context.
  3. // 初始化类型转换器
  4. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
  5. beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
  6. beanFactory.setConversionService(
  7. beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
  8. }
  9. // Register a default embedded value resolver if no bean post-processor
  10. // (such as a PropertyPlaceholderConfigurer bean) registered any before:
  11. // at this point, primarily for resolution in annotation attribute values.
  12. // 主要用于注释属性值的解析
  13. if (!beanFactory.hasEmbeddedValueResolver()) {
  14. beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
  15. }
  16. // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
  17. // 尽早初始化 LoadTimeWeaverAware Bean,以便尽早注册其转换器。
  18. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
  19. for (String weaverAwareName : weaverAwareNames) {
  20. getBean(weaverAwareName);
  21. }
  22. // Stop using the temporary ClassLoader for type matching.
  23. // 停止使用临时的ClassLoader进行类型匹配。
  24. beanFactory.setTempClassLoader(null);
  25. // Allow for caching all bean definition metadata, not expecting further changes.
  26. // 设置 beanDefinition 元数据 不可以再修改
  27. beanFactory.freezeConfiguration();
  28. // Instantiate all remaining (non-lazy-init) singletons.
  29. // 实例化单例 bean
  30. beanFactory.preInstantiateSingletons();
  31. }

这里重点关注最后一行
beanFactory.preInstantiateSingletons();

preInstantiateSingletons

这块进入的是类 DefaultListableBeanFactory 类的源码。

  1. public void preInstantiateSingletons() throws BeansException {
  2. if (logger.isTraceEnabled()) {
  3. logger.trace("Pre-instantiating singletons in " + this);
  4. }
  5. // Iterate over a copy to allow for init methods which in turn register new bean definitions.
  6. // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
  7. // 将 beanDefinitionNames 放到集合中
  8. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
  9. // Trigger initialization of all non-lazy singleton beans...
  10. // 遍历
  11. for (String beanName : beanNames) {
  12. // 获取 bd 信息, 因为可能 定义了 parentBeanDefinition
  13. RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
  14. // 非抽象, 单例, 且不是懒加载
  15. if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
  16. // 判断是否为 FactoryBean
  17. if (isFactoryBean(beanName)) {
  18. // FactoryBean 需要添加前缀 & ,通过 getBean(&beanName) 获取的是 FactoryBean 本身
  19. Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
  20. if (bean instanceof FactoryBean) {
  21. FactoryBean<?> factory = (FactoryBean<?>) bean;
  22. // 判断是否需要初始化
  23. boolean isEagerInit;
  24. if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
  25. isEagerInit = AccessController.doPrivileged(
  26. (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
  27. getAccessControlContext());
  28. }
  29. else {
  30. isEagerInit = (factory instanceof SmartFactoryBean &&
  31. ((SmartFactoryBean<?>) factory).isEagerInit());
  32. }
  33. // 需要初始化
  34. if (isEagerInit) {
  35. getBean(beanName);
  36. }
  37. }
  38. }
  39. else {
  40. getBean(beanName);
  41. }
  42. }
  43. }
  44. // Trigger post-initialization callback for all applicable beans...
  45. // 如果 Bean 实现了 SmartInitializingSingleton,
  46. // 在这里会统一调用 afterSingletonsInstantiated 方法
  47. for (String beanName : beanNames) {
  48. Object singletonInstance = getSingleton(beanName);
  49. if (singletonInstance instanceof SmartInitializingSingleton) {
  50. StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
  51. .tag("beanName", beanName);
  52. SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
  53. if (System.getSecurityManager() != null) {
  54. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  55. smartSingleton.afterSingletonsInstantiated();
  56. return null;
  57. }, getAccessControlContext());
  58. }
  59. else {
  60. smartSingleton.afterSingletonsInstantiated();
  61. }
  62. smartInitialize.end();
  63. }
  64. }
  65. }

上面方法中通过循环 beanNames 进行初始化 Bean。
其中需要区别 BeanFactory 和 普通 Bean。 这也是我开始为什么先介绍了什么是 BeanFactory ?
下面就需要重点关注 getBean(beanName) 方法。

getBean

  1. public Object getBean(String name) throws BeansException {
  2. return doGetBean(name, null, null, false);
  3. }

getBean 方法中调用的是 doGetBean 方法。

doGetBean

doGetBean 方法作用是:返回一个实例,该实例可以是指定bean的共享或独立的
该方法接受四个参数:

name – 要检索的 bean 的名称 requiredType – 要检索的 bean 的必需类型,这个可以为空 args –使用显式参数创建bean实例时要使用的参数(仅在创建新实例而不是检索现有实例时才应用) typeCheckOnly –是否为类型检查而不是实际使用获取实例

  1. protected <T> T doGetBean(
  2. String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
  3. throws BeansException {
  4. // 去掉工厂引用的前缀, 同时转换别名
  5. String beanName = transformedBeanName(name);
  6. Object bean;
  7. // Eagerly check singleton cache for manually registered singletons.
  8. // 从缓存中检查单例是否已经存在
  9. Object sharedInstance = getSingleton(beanName);
  10. if (sharedInstance != null && args == null) {
  11. if (logger.isTraceEnabled()) {
  12. if (isSingletonCurrentlyInCreation(beanName)) {
  13. logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
  14. "' that is not fully initialized yet - a consequence of a circular reference");
  15. }
  16. else {
  17. logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
  18. }
  19. }
  20. // 从缓存中如果获取到了, 普通 Bean 直接返回, FactoryBean 则返回 FactoryBean 创建的 Bean
  21. bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
  22. }
  23. else {
  24. // Fail if we're already creating this bean instance:
  25. // We're assumably within a circular reference.
  26. // 返回指定的 原型bean (prototype 类型的 Bean) 是否当前正在创建中(在当前线程内)。
  27. if (isPrototypeCurrentlyInCreation(beanName)) {
  28. throw new BeanCurrentlyInCreationException(beanName);
  29. }
  30. // Check if bean definition exists in this factory.
  31. // 检查 BeanFactory 是否存在这个 Bean 的 BeanDefinition
  32. BeanFactory parentBeanFactory = getParentBeanFactory();
  33. if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
  34. // Not found -> check parent.
  35. // 检查父容器中有没有定义
  36. String nameToLookup = originalBeanName(name);
  37. // 返回从父容器中查询的结果
  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. if (!typeCheckOnly) {
  55. // 将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
  56. // 标识本次调用方法,并非是要获取bean的类型,而是为了创建实例,将beanName存到alreadyCreated集合,代表该bean已经创建了,后面try。。catch有异常会清空该beanName
  57. markBeanAsCreated(beanName);
  58. }
  59. StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
  60. .tag("beanName", name);
  61. try {
  62. if (requiredType != null) {
  63. beanCreation.tag("beanType", requiredType::toString);
  64. }
  65. // 获取 Bean 的 BeanDefinition
  66. RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
  67. checkMergedBeanDefinition(mbd, beanName, args);
  68. // Guarantee initialization of beans that the current bean depends on.
  69. // 确保依赖的 Bean 已经被初始化, 比如 @DependsOn 注解
  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. // 创建依赖的 Bean
  80. getBean(dep);
  81. }
  82. catch (NoSuchBeanDefinitionException ex) {
  83. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  84. "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
  85. }
  86. }
  87. }
  88. // Create bean instance.
  89. if (mbd.isSingleton()) {
  90. // 单例 bean
  91. sharedInstance = getSingleton(beanName, () -> {
  92. try {
  93. return createBean(beanName, mbd, args);
  94. }
  95. catch (BeansException ex) {
  96. // Explicitly remove instance from singleton cache: It might have been put there
  97. // eagerly by the creation process, to allow for circular reference resolution.
  98. // Also remove any beans that received a temporary reference to the bean.
  99. destroySingleton(beanName);
  100. throw ex;
  101. }
  102. });
  103. bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
  104. }
  105. // 创建原型Bean
  106. else if (mbd.isPrototype()) {
  107. // It's a prototype -> create a new instance.
  108. Object prototypeInstance = null;
  109. try {
  110. beforePrototypeCreation(beanName);
  111. prototypeInstance = createBean(beanName, mbd, args);
  112. }
  113. finally {
  114. afterPrototypeCreation(beanName);
  115. }
  116. bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
  117. }
  118. else {
  119. // 委托给实现类处理
  120. String scopeName = mbd.getScope();
  121. if (!StringUtils.hasLength(scopeName)) {
  122. throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
  123. }
  124. Scope scope = this.scopes.get(scopeName);
  125. if (scope == null) {
  126. throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
  127. }
  128. try {
  129. Object scopedInstance = scope.get(beanName, () -> {
  130. beforePrototypeCreation(beanName);
  131. try {
  132. return createBean(beanName, mbd, args);
  133. }
  134. finally {
  135. afterPrototypeCreation(beanName);
  136. }
  137. });
  138. bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
  139. }
  140. catch (IllegalStateException ex) {
  141. throw new ScopeNotActiveException(beanName, scopeName, ex);
  142. }
  143. }
  144. }
  145. catch (BeansException ex) {
  146. beanCreation.tag("exception", ex.getClass().toString());
  147. beanCreation.tag("message", String.valueOf(ex.getMessage()));
  148. cleanupAfterBeanCreationFailure(beanName);
  149. throw ex;
  150. }
  151. finally {
  152. beanCreation.end();
  153. }
  154. }
  155. // Check if required type matches the type of the actual bean instance.
  156. // 检查所需的类型是否与实际bean实例的类型匹配。
  157. if (requiredType != null && !requiredType.isInstance(bean)) {
  158. try {
  159. T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
  160. if (convertedBean == null) {
  161. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  162. }
  163. return convertedBean;
  164. }
  165. catch (TypeMismatchException ex) {
  166. if (logger.isTraceEnabled()) {
  167. logger.trace("Failed to convert bean '" + name + "' to required type '" +
  168. ClassUtils.getQualifiedName(requiredType) + "'", ex);
  169. }
  170. throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
  171. }
  172. }
  173. return (T) bean;
  174. }

上面代码比较长,基本上步骤已经添加相应的注释,基本上可以分为三步:

  1. 从缓存中获取到 Bean,创建对应的 Bean;
  2. 没有从缓存中获取到 Bean,创建对应的 Bean;
  3. 检查所需的类型是否与实际bean实例的类型匹配。

下面从这三个步骤分别介绍:

  • 从缓存中获取到 Bean,创建对应的 Bean

**Object sharedInstance = getSingleton(beanName);**

  1. public Object getSingleton(String beanName) {
  2. return getSingleton(beanName, true);
  3. }
  4. /**
  5. * 返回以给定名称注册的(原始)单例对象。
  6. *
  7. * 检查已经实例化的单例,并允许早期引用当前创建的单例(解析循环引用)
  8. */
  9. @Nullable
  10. protected Object getSingleton(String beanName, boolean allowEarlyReference) {
  11. // Quick check for existing instance without full singleton lock
  12. // private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
  13. // 缓存了 单例 Bean
  14. Object singletonObject = this.singletonObjects.get(beanName);
  15. // 如果没有获取到, 并且当前 Bean 正在被创建中
  16. if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
  17. // private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
  18. // 早期的单例对象, 先从 earlySingletonObjects 中获取
  19. singletonObject = this.earlySingletonObjects.get(beanName);
  20. // 没有从 earlySingletonObjects 缓存中获取到
  21. if (singletonObject == null && allowEarlyReference) {
  22. synchronized (this.singletonObjects) {
  23. // Consistent creation of early reference within full singleton lock
  24. // 再次获取并检查
  25. singletonObject = this.singletonObjects.get(beanName);
  26. if (singletonObject == null) {
  27. singletonObject = this.earlySingletonObjects.get(beanName);
  28. if (singletonObject == null) {
  29. // private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
  30. // 从 singletonFactories 缓存中获取
  31. ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
  32. if (singletonFactory != null) {
  33. singletonObject = singletonFactory.getObject();
  34. // 添加到 earlySingletonObjects 缓存中
  35. this.earlySingletonObjects.put(beanName, singletonObject);
  36. // 从 singletonFactories 缓存中删除
  37. this.singletonFactories.remove(beanName);
  38. }
  39. }
  40. }
  41. }
  42. }
  43. }
  44. return singletonObject;
  45. }

这里可以看出,获取一个 Bean :

  1. 先从 singletonObjects 中获取 Bean;
  2. 获取不到,从 earlySingletonObjects 中获取 Bean;
  3. 获取不到,从 singletonFactories 中获取 Bean。

当然这一块涉及到循环引用,篇幅有限,后面会专门介绍循环引用。

  • 没有从缓存中获取到 Bean,创建对应的 Bean ```java // Create bean instance. if (mbd.isSingleton()) { // 单例 bean sharedInstance = getSingleton(beanName, () -> {
    1. try {
    2. return createBean(beanName, mbd, args);
    3. }
    4. catch (BeansException ex) {
    5. // Explicitly remove instance from singleton cache: It might have been put there
    6. // eagerly by the creation process, to allow for circular reference resolution.
    7. // Also remove any beans that received a temporary reference to the bean.
    8. destroySingleton(beanName);
    9. throw ex;
    10. }
    }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 创建原型Bean

} else { // 委托给实现类处理 String scopeName = mbd.getScope(); } ```