Spring IOC源码分析-finishBeanFactoryInitialization

675 阅读8分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

前言

Finish the initialization of this context's bean factory, Instantiate all remaining (non-lazy-init) singletons.

该方法主要做普通Bean的创建和初始化.该方法会实例化所有剩余的非懒加载单例 bean。

Spring 源码分析系列

下面回顾一下refresh的12个步骤 image.png

源码分析

1. finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // Initialize conversion service for this context.
   // 1. 初始化上下文转换服务
   if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
         beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
      beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
   }

   // Register a default embedded value resolver if no BeanFactoryPostProcessor
   // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
   // at this point, primarily for resolution in annotation attribute values.
   // 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
   // 3. 初始化LoadTimeWeaverAware Bean实例对象
   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   // Stop using the temporary ClassLoader for type matching.
   beanFactory.setTempClassLoader(null);

   // Allow for caching all bean definition metadata, not expecting further changes.
   // 4. 冻结所有bean定义,因为马上要创建 Bean 实例对象了
   beanFactory.freezeConfiguration();

   // Instantiate all remaining (non-lazy-init) singletons.
   // 5. 实例化所有剩余(非懒加载)单例对象
   beanFactory.preInstantiateSingletons();
}

2. preInstantiateSingletons

@Override
public void preInstantiateSingletons() throws BeansException {
   if (logger.isTraceEnabled()) {
      logger.trace("Pre-instantiating singletons in " + this);
   }

   // Iterate over a copy to allow for init methods which in turn register new bean definitions.
   // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
   // 1.创建beanDefinitionNames的副本beanNames用于后续的遍历,以允许init等方法注册新的bean定义
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   // Trigger initialization of all non-lazy singleton beans...
   // 2.遍历beanNames,触发所有非懒加载单例bean的初始化
   for (String beanName : beanNames) {
      // 3.获取beanName 对应的 MergedBeanDefinition
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      // 4.bd对应的Bean实例:不是抽象类 && 是单例 && 不是懒加载
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         // 5.判断beanName对应的bean是否为FactoryBean
         if (isFactoryBean(beanName)) {
            // 5.1 通过beanName获取FactoryBean实例
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               // 5.2 判断这个FactoryBean是否希望急切的初始化
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  // 5.3 如果希望急切的初始化,则通过beanName获取bean实例
                  getBean(beanName);
               }
            }
         }
         else {
            // 6.如果beanName对应的bean不是FactoryBean,只是普通Bean,通过beanName获取bean实例
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   // 7.遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
   for (String beanName : beanNames) {
      // 7.1 获取beanName对应的bean实例
      Object singletonInstance = getSingleton(beanName);
      // 7.2 判断singletonInstance是否实现了SmartInitializingSingleton接口
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         // 7.3 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

3. getMergedLocalBeanDefinition

MergedBeanDefinition 合并的Bean定义,之所以称为合并Bean定义,是因为存在父子关系.

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
   // Quick check on the concurrent map first, with minimal locking.
   // 先查询缓存有没有
   RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
   if (mbd != null && !mbd.stale) {
      return mbd;
   }
   // 根据 beanName 和 beanName 对应的 BeanDefinition,获取 MergedBeanDefinition
   return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
      throws BeanDefinitionStoreException {
   return getMergedBeanDefinition(beanName, bd, null);
}

4. getMergedBeanDefinition

protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

   // 1. 枷锁
   synchronized (this.mergedBeanDefinitions) {
      RootBeanDefinition mbd = null;
      RootBeanDefinition previous = null;

      // Check with full lock now in order to enforce the same merged instance.
      // 2.检查beanName对应的MergedBeanDefinition是否存在于缓存中
      if (containingBd == null) {
         mbd = this.mergedBeanDefinitions.get(beanName);
      }

      // 3.如果beanName对应的MergedBeanDefinition不存在于缓存中
      if (mbd == null || mbd.stale) {
         previous = mbd;
         if (bd.getParentName() == null) {
            // Use copy of given root bean definition.
            // 4.如果bd的parentName为空,代表bd没有父定义,无需与父定义进行合并操作
            if (bd instanceof RootBeanDefinition) {
               // 4.1 如果bd的类型为RootBeanDefinition,则直接克隆一个副本
               mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
               // 4.2 否则,构建一个RootBeanDefinition
               mbd = new RootBeanDefinition(bd);
            }
         }
         else {
            // Child bean definition: needs to be merged with parent.
            // 5.否则,bd存在父定义,需要与父定义合并
            BeanDefinition pbd;
            try {
               // 5.1 获取父定义的beanName
               String parentBeanName = transformedBeanName(bd.getParentName());
               // 5.2 如果父定义的beanName与该bean的beanName不同
               if (!beanName.equals(parentBeanName)) {
                  // 5.3 递归获取父定义的MergedBeanDefinition
                  pbd = getMergedBeanDefinition(parentBeanName);
               }
               else {
                  // 5.4 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory,
                  BeanFactory parent = getParentBeanFactory();
                  if (parent instanceof ConfigurableBeanFactory) {
                     // 5.5 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition
                     pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                  }
                  else {
                     // 5.6 如果不是,直接抛异常
                     throw new NoSuchBeanDefinitionException(parentBeanName,
                           "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                           "': cannot be resolved without a ConfigurableBeanFactory parent");
                  }
               }
            }
            catch (NoSuchBeanDefinitionException ex) {
               throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                     "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
            }
            // Deep copy with overridden values.
            // 5.7 使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)
            mbd = new RootBeanDefinition(pbd);
            // 5.8 使用bd覆盖父定义
            mbd.overrideFrom(bd);
         }

         // Set default singleton scope, if not configured before.
         // 6.如果没有配置scope,则设置成默认的singleton
         if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(SCOPE_SINGLETON);
         }

         // A bean contained in a non-singleton bean cannot be a singleton itself.
         // Let's correct this on the fly here, since this might be the result of
         // parent-child merging for the outer bean, in which case the original inner bean
         // definition will not have inherited the merged outer bean's singleton status.
         // 7.如果containingBd不为空 && containingBd不为singleton && mbd为singleton
         // 则将mdb的scope设置为containingBd的scope
         if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
            mbd.setScope(containingBd.getScope());
         }

         // Cache the merged bean definition for the time being
         // (it might still get re-merged later on in order to pick up metadata changes)
         // 8.将beanName与mbd放到mergedBeanDefinitions缓存,以便之后可以直接使用
         if (containingBd == null && isCacheBeanMetadata()) {
            this.mergedBeanDefinitions.put(beanName, mbd);
         }
      }
      if (previous != null) {
         copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      // 9.返回MergedBeanDefinition
      return mbd;
   }
}

5. transformedBeanName

将 name 真正解析成真正的 beanName,主要是去掉 FactoryBean 里的 “&” 前缀,和解析别名。

protected String transformedBeanName(String name) {
   return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

// beanName 转换
public static String transformedBeanName(String name) {
   Assert.notNull(name, "'name' must not be null");
   if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
      return name;
   }
   return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
      do {
         beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
      }
      while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
      return beanName;
   });
}

// 将别名解析成真正的beanName
public String canonicalName(String name) {
   String canonicalName = name;
   // Handle aliasing...
   String resolvedName;
   do {
      resolvedName = this.aliasMap.get(canonicalName);
      if (resolvedName != null) {
        canonicalName = resolvedName;
      }
   }
   while (resolvedName != null);
   return canonicalName;
}

FactoryBean 和 BeanFactory的区别

BeanFactory 是 Bean 的工厂, ApplicationContext 的父类,IOC 容器的核心,负责生产和管理 Bean 对象。
FactoryBean 是 Bean,可以通过实现 FactoryBean 接口定制实例化 Bean 的逻辑,通过代理一个Bean对象,对方法前后做一些操作。

6. getMergedBeanDefinition

父子容器 BeanFactory

在 Spring 中可能存在多个 BeanFactory,多个 BeanFactory 可能存在 “父工厂” 与 “子工厂” 的关系。

最常见的例子就是

Spring MVC 的 BeanFactory 和 Spring 的 BeanFactory,通常情况下,Spring 的 BeanFactory 是 “父工厂”,Spring MVC 的 BeanFactory 是 “子工厂”,在 Spring 中,子工厂可以使用父工厂的 BeanDefinition,因而,如果在当前 BeanFactory 中找不到,而又存在父工厂,则会去父工厂中查找。

@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
   //1.获取真正的beanName(解析别名)
   String beanName = transformedBeanName(name);
   // Efficiently check whether bean definition exists in this factory.
   // 2.如果当前BeanFactory中不存在beanName的Bean定义 && 父beanFactory是ConfigurableBeanFactory,
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // 调用父BeanFactory去获取beanName的MergedBeanDefinition
      return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
   }
   // Resolve merged bean definition locally.
   // 3.在当前BeanFactory中解析beanName的MergedBeanDefinition
   return getMergedLocalBeanDefinition(beanName);
}

7. isFactoryBean

@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
   // 1.获取真正的beanName(去掉&前缀、解析别名)
   String beanName = transformedBeanName(name);
   // 2. 尝试从缓存获取Bean实例对象
   Object beanInstance = getSingleton(beanName, false);
   if (beanInstance != null) {
      // 3.beanInstance存在,则直接判断类型是否为FactoryBean
      return (beanInstance instanceof FactoryBean);
   }
   // No singleton instance found -> check bean definition.
   if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
      // No bean definition found in this factory -> delegate to parent.
      // 5.如果缓存中不存在此beanName && 父beanFactory是ConfigurableBeanFactory
      // 则调用父BeanFactory判断是否为FactoryBean
      return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
   }
   // 6.通过MergedBeanDefinition来检查beanName对应的Bean是否为FactoryBean
   return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}

8. getSingleton

经典的三级缓存代码, 常见面试题目如何解决循环依赖? 为什么要三级缓存,二级缓存是不是就行了等等?

spring内部有三级缓存

  • singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
  • earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例
  • singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   // Quick check for existing instance without full singleton lock
   // 1.从单例对象缓存中获取beanName对应的单例对象
   Object singletonObject = this.singletonObjects.get(beanName);
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      // 2.如果单例对象缓存中没有,并且该beanName对应的单例bean正在创建中
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
         // 3.加锁进行操作
         synchronized (this.singletonObjects) {
            // Consistent creation of early reference within full singleton lock
            // 4.从早期单例对象缓存中获取单例对象(一级缓存)
            // 之所称成为早期单例对象,是因为earlySingletonObjects里的对象的都是通过提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作
            singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
               singletonObject = this.earlySingletonObjects.get(beanName);
               if (singletonObject == null) {
                  // 6.从单例工厂缓存中获取beanName的单例工厂
                  ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                  if (singletonFactory != null) {
                     // 7.如果存在单例对象工厂,则通过工厂创建一个单例对象
                     singletonObject = singletonFactory.getObject();
                     // 8.将通过单例对象工厂创建的单例对象,放到早期单例对象缓存中
                     this.earlySingletonObjects.put(beanName, singletonObject);
                     // 9.移除该beanName对应的单例对象工厂,因为该单例工厂已经创建了一个实例对象,并且放到earlySingletonObjects缓存了,
                     // 因此,后续获取beanName的单例对象,可以通过earlySingletonObjects缓存拿到,不需要在用到该单例工厂
                     this.singletonFactories.remove(beanName);
                  }
               }
            }
         }
      }
   }
   return singletonObject;
}

9. isFactoryBean

protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
   Boolean result = mbd.isFactoryBean;
   if (result == null) {
      // 1. 获取beanName对应的Bean实例的类型
      Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
      // 2.返回beanType是否为FactoryBean本身、子类或子接口
      result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
      mbd.isFactoryBean = result;
   }
   return result;
}

10. predictBeanType

@Nullable
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
   Class<?> targetType = mbd.getTargetType();
   if (targetType != null) {
      return targetType;
   }
   if (mbd.getFactoryMethodName() != null) {
      return null;
   }
   return resolveBeanClass(mbd, beanName, typesToMatch);
}

最后

回顾一下 finishBeanFactoryInitialization 主要功能普通Bean的创建和初始化. 还有一些非常容易混淆的概念

  1. MergedBeanDefinition 合并BeanDefinition
  2. FactoryBean 和 BeanFactory的区别
  3. 父子容器 BeanFactory
  4. spring内部有三级缓存, singletonObjects, earlySingletonObjects,singletonFactories