Spring解决循环依赖


前言

这篇文章是接着前一篇SpringIOC容器加载流程和源码剖析一起的。主要内容Spring Bean定义到Bean的过程以及源码剖析和部分Spring的扩展节点。

这里我们从refresh->finishBeanFactoryInitialization开始看

循环依赖

什么是循环依赖,循环依赖就是A依赖B,B依赖A,这就产生了循环依赖。比如说A类注入了B类,B类注入了A类,这时候我调用bean工厂的getBean方法就会产生循环依赖,具体过程是getBean(A);

  1. bean工厂生产beanA,发现A里面注入了B,我们就要getBean(B)
  2. bean工厂生产beanB,发现B里面注入了A,我们就要getBean(A)

此时产生了死循环,这就是循环依赖,那么我们看spring是怎样解决的?

spring用了传说中的三级缓存

// 一级缓存 这个就是单例缓存池,用于保存我们所有的完整的单例bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 三级缓存 该map用户缓存key为beanName value为ObjectFactory(包装为早期对象,钩子方法) 
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

// 二级缓存 用户缓存我们的key为beanName value是我们的早期对象(对象属性还没有来得及进行赋值)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

// 用户缓存当前正在创建bean的名称
private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

这里简单说下spring解决循环依赖过程,详细源码在下面

我们还是以上面的例子继续说

  1. bean工厂开始生产beanA,我们会先从一级缓存中看是不是存在,存在直接返回,不存在就在singletonsCurrentlyInCreation集合里面看是不是存在,这时候肯定是不存在的
  2. 从一级缓存没有拿到,就开始创建bean,首先把当前bean放在singletonsCurrentlyInCreation集合里面,表示正在创建
  3. 实例化bean,并把一个创建早期方法的钩子方法放在三级缓存中
  4. 属性赋值,循环所有属性拿到Autowired,找到注入的属性B,然后getBean(B)
  5. getBean(B)的过程中走了1~4步,然后肯定会再次执行getBean(A)
  6. 这时候会先从一级缓存中看是不是存在,不存在,就再在singletonsCurrentlyInCreation集合里面看是不是存在,这时候是存在
  7. 再从二级缓存中拿,二级缓存也没有,这时候从三级缓存中拿,找到了钩子方法,调用钩子方法获得早期对象,把早期对象放到二级缓存,然后返回。
  8. 这时候B中的A是一个代理对象,原实例A是正在属性赋值过程中。接下来B属性赋值结束,从三级,二级,当前创建这几个集合中移除B,一级缓存加入B
  9. B创建完成,来到A,A继续走,放入一级缓存,getBean(A)结束。

这里三级缓存的钩子方法是通过后置处理器解决的是SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference;可以通过这里进行扩展。

为什么需要二级缓存?

二级缓存是为了分离成熟Bean和纯净Bean(未注入属性)的存放, 防止多线程中在Bean还未创建完成时读取到的Bean时不完整的。所
以也是为了保证我们getBean是完整最终的Bean。

为什么需要三级缓存?

Bean的AOP动态代理创建在bean初始化之后,但是循环依赖的Bean,会在循环的时候就创建好了bean,这时候在创建动态代理就晚了,属性已经注入。如果循环依赖的Bean使用了AOP, 需要提前创建AOP。

三级缓存的存在主要是位为了解耦和解决循环依赖的AOP。

实例化Bean源码

finishBeanFactoryInitialization方法

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   // 为我们的bean工厂创建类型转化器
   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));
   }
    
   if (!beanFactory.hasEmbeddedValueResolver()) {
      beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
   }

   String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
   for (String weaverAwareName : weaverAwareNames) {
      getBean(weaverAwareName);
   }

   beanFactory.setTempClassLoader(null);

   // 冻结所有的bean定义,这时候Bean定义已经不能通过Bean工厂后置处理器进行修改
   // 这里面实现很简单就是赋值configurationFrozen=true;我们可以通过configurationFrozen这个属性判定Bean定义是否可以修改
   beanFactory.freezeConfiguration();

   //实例化剩余的单实例bean
   beanFactory.preInstantiateSingletons();
}

这一块有2个重点一个是冻结bean定义另一个是实例化单例bean

preInstantiateSingletons方法

public void preInstantiateSingletons() throws BeansException {
   if (logger.isDebugEnabled()) {
      logger.debug("Pre-instantiating singletons in " + this);
   }

   //获取我们容器中所有bean定义的名称,这里是从bean定义名称集合里面去拿,而不是从beanDefinitionMap中拿
   //是由于bean定义是有类型的
   List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

   //循环我们所有的bean定义名称
   for (String beanName : beanNames) {
      //合并我们的bean定义,转换为统一的RootBeanDefinition类型(在), 方便后续处理
      RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      //根据bean定义判断 不是抽象的&&是单例的&&不是懒加载的
      if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
         //是不是工厂bean
         if (isFactoryBean(beanName)) {
            // 是factoryBean会先生成实际的bean  &beanName 是用来获取实际bean的
            Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
            if (bean instanceof FactoryBean) {
               final FactoryBean<?> factory = (FactoryBean<?>) bean;
               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());
               }
               //调用真正的getBean的流程
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
             //非工厂Bean 就是普通的bean
            getBean(beanName);
         }
      }
   }

   //所有的单例bean已经缓存单例bean到一级缓存singletonObjects
   for (String beanName : beanNames) {
      //从单例缓存池中获取所有的对象
      Object singletonInstance = getSingleton(beanName);
      //判断当前的bean是否实现了SmartInitializingSingleton接口,
      // 在初期注册的6个后置处理器中有一个是实现了这个接口就是处理监听方法的注解@EventListener解析器EventListenerMethodProcessor
      if (singletonInstance instanceof SmartInitializingSingleton) {
         final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            //触发实例化之后的方法afterSingletonsInstantiated
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

这里主要是开始解析成bean的前期准备工作和,解析完后的扩展工作。

前期准备会判断是不是FactoryBean,这里的FactoryBean和BeanFactory是不一样的,后面会做解释。

getBean之后会调用实现了SmartInitializingSingleton接口的实现类,这里是一个扩展点,解析带注解的时间监听器就是这里处理的

其实不管是FactoryBean还是普通Bean都会走getBean这个方法,这个号方法才是解析Bean的最重要的方法。getBean->doGetBean

doGetBean方法

再看getBean前先介绍一下几个集合类

// 一级缓存 这个就是单例缓存池,用于保存我们所有的完整的单例bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 三级缓存 该map用户缓存key为beanName value为ObjectFactory(包装为早期对象,钩子方法) 
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

// 二级缓存 用户缓存我们的key为beanName value是我们的早期对象(对象属性还没有来得及进行赋值)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

// 已注册的单例名称set
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

// 用户缓存当前正在创建bean的名称
private final Set<String> singletonsCurrentlyInCreation =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));

// 排除当前创建检查的
private final Set<String> inCreationCheckExclusions =
            Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
  * @param name bean名称或别名
  * @param requiredType 需要获取bean的类型
  * @param args 通过该参数传递进来,到调用构造方法时候发现有多个构造方法,我们就可以通过该参数来指定想要的构造方法了
  * 不需要去推断构造方法(因为推断构造方法很耗时)
  * @param typeCheckOnly 判断当前的bean是不是一个检查类型的bean,这类型用的很少.
  * @return 返回一个bean实例,该实例可能是单例bean,也有可能是原型bean
  */
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

   //传入进来的name可能是别名, 也有可能是FactoryBean的name,所以在这里需要转换
   final String beanName = transformedBeanName(name);
   Object bean;

   //尝试去缓存中获取对象 --getSingleton重点方法,注意下面也有一个getSingleton,这2者功能不一样--
   Object sharedInstance = getSingleton(beanName);

   //缓存中拿到了
   if (sharedInstance != null && args == null) {
      if (logger.isDebugEnabled()) {
         // 判断是不是当前正在创建的
         if (isSingletonCurrentlyInCreation(beanName)) {
            logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                  "' that is not fully initialized yet - a consequence of a circular reference");
         }
         else {
            logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
         }
      }
      
      //如果sharedInstance是普通的单例bean,下面的方法会直接返回。
      //但如果sharedInstance是FactoryBean,则需调用getObject工厂方法获取真正的bean实例。如果用户想获取FactoryBean本身,这里也不会做特别的处理,直接返回. --这个方法下面源码会剖析--
      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
   } 

   else {

      //spring只能解决单例对象的setter 注入的循环依赖,不能解决构造器注入
      if (isPrototypeCurrentlyInCreation(beanName)) {
         throw new BeanCurrentlyInCreationException(beanName);
      }

      //====================================父子容器,先不用管-Begin=================================
      /**
       * 判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为abstractBeanFactory直接是抽象类,不存在父工厂
       * 一般情况下,只有Spring和SpringMvc整合的时才会有父子容器的概念,
       * 比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
       * 但是当前所在的容器是web子容器,那么就会在这里的先去父容器找
       */
      BeanFactory parentBeanFactory = getParentBeanFactory();
      //若存在父工厂,切当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFacotry中
      if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
         //获取bean的原始名称
         String nameToLookup = originalBeanName(name);
         //若为 AbstractBeanFactory 类型,委托父类处理
         if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                  nameToLookup, requiredType, args, typeCheckOnly);
         }
         else if (args != null) {
            //  委托给构造函数 getBean() 处理
            return (T) parentBeanFactory.getBean(nameToLookup, args);
         }
         else {
            // 没有 args,委托给标准的 getBean() 处理
            return parentBeanFactory.getBean(nameToLookup, requiredType);
         }
      }
     //====================================父子容器,先不用管-END=================================
       
      /**
       * 方法参数typeCheckOnly,是用来判断调用getBean方法时,表示是否为仅仅进行类型检查获取Bean对象
       * 如果不是做类型检查,而是创建Bean对象,则需要调用markBeanAsCreated方法,进行记录
       * 一般都会执行markBeanAsCreated方法, 这个方法比较简单 --这个方法下面源码会剖析--
       */
      if (!typeCheckOnly) {
         markBeanAsCreated(beanName);
      }

      try {
         // 从容器中获取beanName相应的GenericBeanDefinition对象,并将其转换为RootBeanDefinition对象
         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
         //检查当前创建的bean定义是不是抽象的bean定义
         checkMergedBeanDefinition(mbd, beanName, args);

         // ===============================解决@DependsOn的情况,一般不会走,BEGIN============
         /**
           @Bean
           public DependsA dependsA() {
               return new DependsA();
           }
           @Bean
           @DependsOn(value = {"dependsA"})
           public DependsB dependsB() {
              return new DependsB();
           }
           * 处理@DependsOn注解的依赖(这个不是我们所谓的循环依赖,而是bean创建前后的依赖,是我们手动希望在解析这个bean之前需要先解析DependsOn中的方法)
           */
         //依赖bean的名称
         String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
            // 若给定的依赖bean已经注册为依赖给定的 bean
            // 即循环依赖的情况,抛出 BeanCreationException 异常
            for (String dep : dependsOn) {
               //beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
               if (isDependent(beanName, dep)) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
               }
               //保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
               registerDependentBean(dep, beanName);
               try {
                  //获取depentceOn的bean
                  getBean(dep);
               }
               catch (NoSuchBeanDefinitionException ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
               }
            }
         }
         // ===============================解决@DependsOn的情况,一般不会走,END============
          
         // ===============================创建单例bean,重点必看,START=======================
         if (mbd.isSingleton()) {
            //把beanName和一个singletonFactory,并且传入一个回调对象 --带回调的getSingleton方法源码分析--
            sharedInstance = getSingleton(beanName, () -> {
               try {
                  //进入创建bean的逻辑 --重点逻辑,下面源码分析--
                  return createBean(beanName, mbd, args);
               }
               catch (BeansException ex) {
                  //创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
                  destroySingleton(beanName);
                  throw ex;
               }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
         }
        // ===============================创建单例bean,重点必看,END=======================
          
         // ===============================创建多例bean,暂时忽略,START=======================
         else if (mbd.isPrototype()) {
            // It's a prototype -> create a new instance.
            Object prototypeInstance = null;
            try {
               beforePrototypeCreation(beanName);
               prototypeInstance = createBean(beanName, mbd, args);
            }
            finally {
               afterPrototypeCreation(beanName);
            }
            bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
         }
        // ===============================创建多例bean,暂时忽略,END=======================
         else {
            String scopeName = mbd.getScope();
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
               throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            try {
               Object scopedInstance = scope.get(beanName, () -> {
                  beforePrototypeCreation(beanName);
                  try {
                     return createBean(beanName, mbd, args);
                  }
                  finally {
                     afterPrototypeCreation(beanName);
                  }
               });
               bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
            catch (IllegalStateException ex) {
               throw new BeanCreationException(beanName,
                     "Scope '" + scopeName + "' is not active for the current thread; consider " +
                     "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                     ex);
            }
         }
      }
      catch (BeansException ex) {
         cleanupAfterBeanCreationFailure(beanName);
         throw ex;
      }
   }

   // Check if required type matches the type of the actual bean instance.
   if (requiredType != null && !requiredType.isInstance(bean)) {
      try {
         T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
         if (convertedBean == null) {
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
         }
         return convertedBean;
      }
      catch (TypeMismatchException ex) {
         if (logger.isDebugEnabled()) {
            logger.debug("Failed to convert bean '" + name + "' to required type '" +
                  ClassUtils.getQualifiedName(requiredType) + "'", ex);
         }
         throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
      }
   }
   return (T) bean;
}

getObjectForBeanInstance方法

获取Bean实例,如果普通bean(包含工厂bean中的&beanname)直接返回,工厂bean调用getObject返回

protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

   //如果 name以&开头,但beanInstance 却不是FactoryBean,则认为有问题。
   if (BeanFactoryUtils.isFactoryDereference(name)) {
      if (beanInstance instanceof NullBean) {
         return beanInstance;
      }
      if (!(beanInstance instanceof FactoryBean)) {
         throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
      }
   }

   // 如果是一个普通的 bean或&beanname直接返回beanInstance
   // 否则就是FactoryBean,需要调用工厂方法生成一个bean实例。
   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
      return beanInstance;
   }

   // ========================下面表示了它是一个FactoryBean--START=================
   Object object = null;
   // mbd 不为空说明当前不是创建,是获取bean的操作
   if (mbd == null) {
      // 从缓存中拿, 第一次肯定没有缓存, 在下面getObjectFromFactoryBean缓存的
      object = getCachedObjectForFactoryBean(beanName);
   }
   if (object == null) {
      // 经过前面的判断,到这里可以保证 beanInstance 是 FactoryBean 类型的,所以可以进行类型转换
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // 如果 mbd 为空,则判断是否存在名字为 beanName 的 BeanDefinition
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
       
      // TODO 暂不清楚
      boolean synthetic = (mbd != null && mbd.isSynthetic());

      // 在这里会调用getObject()
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   // ========================下面表示了它是一个FactoryBean--END=================
   return object;
}

markBeanAsCreated方法

标记Bean是否创建

protected void markBeanAsCreated(String beanName) {
   //没有创建
   if (!this.alreadyCreated.contains(beanName)) {
      //全局加锁
      synchronized (this.mergedBeanDefinitions) {
         //再次检查一次:DCL 双检查模式
         if (!this.alreadyCreated.contains(beanName)) {
            //从 mergedBeanDefinitions 中删除 beanName,并在下次访问时重新创建它
            clearMergedBeanDefinition(beanName);
            // 添加到已创建 bean 集合中
            this.alreadyCreated.add(beanName);
         }
      }
   }
}

带回调的getSingleton方法

// singletonFactory 是一个回调方法,在这个回调方法中执行createBean方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
   Assert.notNull(beanName, "Bean name must not be null");
   //加锁
   synchronized (this.singletonObjects) {
      //尝试从单例缓存池中获取对象
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
         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 + "'");
         }
      
         // 标记当前的bean马上就要被创建了
         // singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖(构造器注入会抛出异常)
         beforeSingletonCreation(beanName);
         boolean newSingleton = false;
         boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
         if (recordSuppressedExceptions) {
            this.suppressedExceptions = new LinkedHashSet<>();
         }
         try {
            // 初始化bean,这里调用钩子方法 createBean方法
            singletonObject = singletonFactory.getObject();
            newSingleton = true;
         }
         catch (IllegalStateException ex) {
            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标记正在创建的bean从集合中移除
            afterSingletonCreation(beanName);
         }
         if (newSingleton) {
            //加入到单例缓存池中,从三级缓存中移除,从二级缓存中移除,记录保存已经处理的bean
            //this.singletonObjects.put(beanName, singletonObject);
           //this.singletonFactories.remove(beanName);
           //this.earlySingletonObjects.remove(beanName);
           //this.registeredSingletons.add(beanName);
            addSingleton(beanName, singletonObject);
         }
      }
      return singletonObject;
   }
}

createBean方法

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   if (logger.isDebugEnabled()) {
      logger.debug("Creating instance of bean '" + beanName + "'");
   }
   RootBeanDefinition mbdToUse = mbd;

   // 确保此时的bean已经被解析了
   Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
   }
   // Prepare method overrides.
   try {
      mbdToUse.prepareMethodOverrides();
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
            beanName, "Validation of method overrides failed", ex);
   }

   try {
       // 通过bean的后置处理器来进行后置处理生成代理对象,一般情况下在此处不会生成代理对象,为什么不能生成代理对象,不管是我们的jdk代理还是cglib代理都不会在此处进行代理,因为我们的真实的对象没有生成,所以在这里不会生成代理对象,那么在这一步是我们aop和事务的关键,因为在这里解析我们的aop切面信息进行缓存
       // --这个方法挺重要的里面包含了几个扩展点 resolveBeforeInstantiation方法源码分析--
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      // 该步骤是我们真正的创建我们的bean的实例对象的过程--重要代码,后续doCreateBean方法源码分析--
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isDebugEnabled()) {
         logger.debug("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);
   }
}

getSingleton方法

// allowEarlyReference通过这个参数可以控制解决循环依赖
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   /**
    * 1: 我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的)
    * IOC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空
    */
   Object singletonObject = this.singletonObjects.get(beanName);
   /**
    * 若在第一级缓存中没有获取到对象,并且singletonsCurrentlyInCreation这个list包含该beanName
    * IOC容器初始化加载单实例bean的时候第一次进来的时候,该list中一般返回空,但是循环依赖的时候可以满足该条件
    */
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         /**
          * 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象)
          * 何为早期对象:就是bean刚刚调用了构造方法,还来不及给bean的属性进行赋值的对象(纯净态)
          * 就是早期对象
          */
         singletonObject = this.earlySingletonObjects.get(beanName);
         //二级缓存中也没有获取到对象,allowEarlyReference为true
         if (singletonObject == null && allowEarlyReference) {
            /**
             * 直接从三级缓存中获取 ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在
             * 在ioc后期的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory
             * 暴露到三级缓存中
             */
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            //从三级缓存中获取到对象不为空
            if (singletonFactory != null) {
               /**
                * 在这里通过暴露的ObjectFactory 包装对象中,通过调用他的getObject()来获取我们的早期对象
                * 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理
                */
               singletonObject = singletonFactory.getObject();
               //把早期对象放置在二级缓存,
               this.earlySingletonObjects.put(beanName, singletonObject);
               //ObjectFactory 包装对象从三级缓存中删除掉
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

resolveBeforeInstantiation方法

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   Object bean = null;
   if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      //判断容器中是否有InstantiationAwareBeanPostProcessors
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
         //获取当前bea的class对象
         Class<?> targetType = determineTargetType(beanName, mbd);
         if (targetType != null) {
            //后置处理器的【第一次】调用 总共有九处调用 事务在这里不会被调用,aop的才会被调用,因为在此处需要解析出对应的切面报错到缓存中,InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
            bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
            //若InstantiationAwareBeanPostProcessors后置处理器的postProcessBeforeInstantiation返回不为null
            //说明生成了代理对象那么我们就调用
            if (bean != null) {
               // 后置处理器的再次调用,该后置处理器若被调用的话,那么第一处的处理器肯定返回的不是null
               // InstantiationAwareBeanPostProcessors后置处理器postProcessAfterInitialization
               bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
            }
         }
      }
      mbd.beforeInstantiationResolved = (bean != null);
   }
   return bean;
}

doCreateBean方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   //BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      //从没有完成的FactoryBean中移除
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      //创建bean实例化 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化 该方法很复杂也很重要
      //这里进行了【第二次】bean后置处理器的调用, SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   //从beanWrapper中获取我们的早期对象
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   // Allow post-processors to modify the merged bean definition.
   synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
         try {
            //进行后置处理 @AutoWired @Value的注解的预解析
            //【第三次】bean后置处理器调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
            applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
         }
         catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                  "Post-processing of merged bean definition failed", ex);
         }
         mbd.postProcessed = true;
      }
   }

   /**
    * 缓存单例到三级缓存中,以防循环依赖
    * 判断是否早期引用的Bean,如果是,则允许提前暴露引用
    * 判断是否能够暴露早期对象的条件:
    * 是否单例
    * 是否允许循环依赖
    * 是否正在创建的Bean
    */
   boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
         isSingletonCurrentlyInCreation(beanName));
   //上述条件满足,允许中期暴露对象
   if (earlySingletonExposure) {
      if (logger.isDebugEnabled()) {
         logger.debug("Eagerly caching bean '" + beanName +
               "' to allow for resolving potential circular references");
      }
      //把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,该方法内部调用getEarlyBeanReference方法
      //【第四次】bean后置处理器调用,通过回调方法调用
      // SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
      //属性赋值 给我们的属性进行赋值(调用set方法进行赋值)
      //【第五次】bean后置处理器调用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
      //【第六次】bean后置处理器调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues
      populateBean(beanName, mbd, instanceWrapper);
      //进行对象初始化操作(在这里可能生成代理对象)
      //【第七次】bean后置处理器调用 BeanPostProcessors.postProcessBeforeInitialization 初始化前调用解决@PostConstruct注解,在这里会调用ApplicationContextAwareProcessor.postProcessBeforeInitialization里面会调用7个*Aware方法,包括EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware
      //【第八次】bean后置处理器调用 BeanPostProcessors.postProcessAfterInitialization aop和事务都会在这里生存代理对象
      //initializeBean里面有一个invokeAwareMethods方法很重要,是调用几个Aware方法,也是扩展点包含BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }

   // 是早期对象暴露
   if (earlySingletonExposure) {
      /**
       * 去缓存中获取到我们的对象 由于传递的allowEarlyReference 是false 要求只能在一级二级缓存中去获取
       * 正常普通的bean(不存在循环依赖的bean) 创建的过程中,压根不会把三级缓存提升到二级缓存中
       */
      Object earlySingletonReference = getSingleton(beanName, false);
      //能够获取到
      if (earlySingletonReference != null) {
         //经过后置处理的bean和早期的bean引用还相等的话(表示当前的bean没有被代理过)
         if (exposedObject == bean) {
            exposedObject = earlySingletonReference;
         }
         //处理依赖的bean
         else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
            String[] dependentBeans = getDependentBeans(beanName);
            Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
            for (String dependentBean : dependentBeans) {
               if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                  actualDependentBeans.add(dependentBean);
               }
            }
            if (!actualDependentBeans.isEmpty()) {
               throw new BeanCurrentlyInCreationException(beanName,
                     "Bean with name '" + beanName + "' has been injected into other beans [" +
                     StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                     "] in its raw version as part of a circular reference, but has eventually been " +
                     "wrapped. This means that said other beans do not use the final version of the " +
                     "bean. This is often the result of over-eager type matching - consider using " +
                     "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
            }
         }
      }
   }

   // Register bean as disposable.
   try {
      //注册销毁的bean的销毁接口
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
   }
   catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
   }

   return exposedObject;
}

这个方法主要是创建Bean,在这个方法最重要的就是8个扩展点也是bean后置处理器调用的几个位置,还有Aware的调用。

BeanFactory和FactoryBean

BeanFasctory顾名思义就是Bean工厂,它是一个容器,是用来生产bean的。

FactoryBean是一个特殊的Bean,如果我们一个普通的Bean实现了FactoryBean接口,接着实现他的2个方法,我们getBean的时候获取到的时候就是实现方法里面的Bean,而不是本身Bean,如果要获取到本身Bean,就要getBean(&beanName).

流程图

![](https://blog-dm.oss-cn-shanghai.aliyuncs.com/articleimage/SpringIOC流程 (1).png)

扩展点

bean的后置处理器扩展点

创建Bean之前

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation:可终止AOP解析切面

实例化过程

SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors:指定实例化构造函数

实例化到属性赋值之间

MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition:@Autowired,@Value预解析

SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference:解决循环依赖AOP

属性赋值

InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation:终止赋值

InstantiationAwareBeanPostProcessor.postProcessPropertyValues:属性配置值修改,@Autowired注入

初始化

BeanPostProcessors.postProcessBeforeInitialization 初始化前调用解决@PostConstruct注解

BeanPostProcessors.postProcessAfterInitialization aop和事务都会在这里生存代理对象

Aware扩展点

初始化之前调用

BeanNameAware

BeanClassLoaderAware

BeanFactoryAware

初始化之前在ApplicationContextAwareProcessor.postProcessBeforeInitialization调用

EnvironmentAware

EmbeddedValueResolverAware

ResourceLoaderAware

ApplicationEventPublisherAware

MessageSourceAware

ApplicationContextAware


文章作者: dm
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 dm !
评论
 上一篇
SpringMVC核心源码剖析 SpringMVC核心源码剖析
SpringMVC是基于MVC的架构模式,MVC是有Model(模型),V(视图),C(控制器)三部分组成的。C负责接收客户端请求,对请求进行处理然后转发到模型进行业务逻辑处理最后转发到相应的V进行显示处理。 SpringMVC执行过程 客
2022-02-26
下一篇 
SpringIOC容器加载流程和源码剖析 SpringIOC容器加载流程和源码剖析
前言说道SpringIOC大家想到的都是控制反转,依赖注入。控制反转是将Bean的创建过程由Spring接手,由Spring创建而不需要我们自己来创建。而依赖注入就是实现控制反转的方式。 SpringIOC基本概念BeanFactorySp
2022-01-15
  目录