spring中bean的生命周期与依赖循环

92 阅读12分钟
  • spring中单例bean的生命周期

    • spring容器中单例bean的生命周期主要分为六个阶段

      • 第一阶段,spring容器启动阶段。 完成了spring的扫描,实例化创建对应beanDefinition对象,注册BeanPostProcessor,以及验证beanDefinition是否合格(验证bean是否抽象,是否单例,是否是FactoryBean以及是否存在dependsOn等等);
      • 第二阶段,bean实例化对象阶段。根据beanDefiniton获取对应的Class对象,推断bean的实例化方式(比如是否存在工厂或静态工厂方式,是否存在supplier机制或者采用哪个构造方法),实例化bean对象,创建bean的包裹对象BeanWrapper;
      • 第三阶段,bean属性填充阶段。调用MergedBeanDefinitionPostProcessor. postProcessMergedBeanDefinition方法判断是否要进行属性填充,并缓存需要属性填充信息 (主要是缓存@Autowired,@Resource的InjectionMetadata注入信息);判断是否支持循环依赖,并提前暴露 bean工厂对象ObjectFactory(是个Lambda表达式),为循环依赖做支持,完成@Autowired,@Resource注解解析,完成属性注入(先完成注解版的手动注入再是自动注入)。
      • 第四阶段,bean的初始化阶段。完成了各种Aware接口的回调(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware 这三个先执行,再是其他Aware接口),然后执行bean生命周期初始化回调方法(遍历BeanPostProcessor列表执行回调方法postProcessBeforeInitialization方法和postProcessAfterInitialization方法, CommonAnnotationBeanPostProcessor.postProcessBeforeInitialization方法中就完成了@PostConstruct注解方法的回调;spring aop就在postProcessAfterInitialization方法中完成了动态代理)
      • 第五阶段,bean的缓存阶段。将bean对象放入单例池中的一级缓存Map<String,Object>singletonObjects中,并删除临时变量缓存,二级缓存和三级缓存
      • 第六阶段,bean的销毁阶段。执行bean销毁方法的回调,以及移除单例池
    • spring中单例bean是的初始化流程

    bean的生命周期.png
    • spring中单例bean是的初始化流程源码阅读解析

      • spring容器启动阶段,初始化spring中非懒加载的单例bean
      @Override
      public void refresh() throws BeansException, IllegalStateException {
         synchronized (this.startupShutdownMonitor) {
                ....
                ....
            try {
               // Allows post-processing of the bean factory in context subclasses.
               postProcessBeanFactory(beanFactory);
      
               StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
               
               // Invoke factory processors registered as beans in the context
               invokeBeanFactoryPostProcessors(beanFactory);
               
               ....
               ....
      
               // Instantiate all remaining (non-lazy-init) singletons.
               // 加载非懒加载的单例bean
               finishBeanFactoryInitialization(beanFactory);
      
      
               // Last step: publish corresponding event.
               finishRefresh();
            }
              ....
              ....
         }
      }
      
      
      • 调用DefaultListableBeanFactory.preInstantiateSingletons方法完成单例bean的加载 在这会验证bean是否单例;是否抽象;是否是Lazy的;是否为FactoryBean,如果是beanName就等于&+beanNames后去调用getBean方法获取对应的bean对象;
      @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.
      
         //遍历BeanDefinition,先从List<String> beanDefinitionNames获取beanNames,然后从
      Map<String, RootBeanDefinition> mergedBeanDefinitions中获取BeanDefinition实例对象
         List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);  
      
         // Trigger initialization of all non-lazy singleton beans...
         for (String beanName : beanNames) {   //为什么不直接遍历map 而是遍历key,然后从map里拿
            //从mergedBeanDefinitions中获取一个BeanDefinition
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
      
            //验证bean是否是抽象的,单例的,是否懒加载的
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
      
               //验证是否是一个FactoryBean
               if (isFactoryBean(beanName)) {
                   //FactoryBean 根据 &+beanName的方法去创建
                  Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                  if (bean instanceof FactoryBean) {
                     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());
                     }
                     if (isEagerInit) {
                        getBean(beanName);
                     }
                  }
               }
               else {
                  //去创建bean
                  getBean(beanName);
               }
            }
         }
      
         // Trigger post-initialization callback for all applicable beans...
         for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
               StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
                     .tag("beanName", beanName);
               SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
               if (System.getSecurityManager() != null) {
                  AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                     smartSingleton.afterSingletonsInstantiated();
                     return null;
                  }, getAccessControlContext());
               }
               else {
                  smartSingleton.afterSingletonsInstantiated();
               }
               smartInitialize.end();
            }
         }
      }
      
      • getBean方法会调用到AbstractBeanFactory.doGetBean方法。
        1.transformedBeanName先验证beanName的合法性
        2.直接从单例池中获取,判断该bean是否被创建过(主要是循环依赖的话,可能二级缓存中存在对应ObjectFactory对象工厂对象)
        3.判断是否是原型bean,是抛BeanCurrentlyInCreationException异常
        4.判断父子容器(spring父子容器)中存在bean对象吗
        5.判断是否存在dependsOn,存在的话应该先去初始化创建dependsOn依赖的bean
        6.创建bean,存在Lambda表达式 先执行getSingleton方法 ,getSingleton方法内部再执行 createBean方法
      protected <T> T doGetBean(
            String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
      
         //验证beanName的合法性
         String beanName = transformedBeanName(name);
         Object beanInstance;
      
         // Eagerly check singleton cache for manually registered singletons.
         //1.直接从单例池中获取,判断该bean是否被创建过
         Object sharedInstance = getSingleton(beanName);
         if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
               if (isSingletonCurrentlyInCreation(beanName)) {
                  logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
               }
               else {
                  logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
               }
            }
            beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
         }
      
         else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            //判断bean是否存在一个正在创建的原型bean集合当中
            if (isPrototypeCurrentlyInCreation(beanName)) {
               throw new BeanCurrentlyInCreationException(beanName);
            }
      
            // Check if bean definition exists in this factory.
            //判断bean是否存在父子容器当中(spring中父子容器问题)
            BeanFactory parentBeanFactory = getParentBeanFactory();
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
               // Not found -> check parent.
               String nameToLookup = originalBeanName(name);
               if (parentBeanFactory instanceof AbstractBeanFactory) {
                  return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                        nameToLookup, requiredType, args, typeCheckOnly);
               }
               else if (args != null) {
                  // Delegation to parent with explicit args.
                  return (T) parentBeanFactory.getBean(nameToLookup, args);
               }
               else if (requiredType != null) {
                  // No args -> delegate to standard getBean method.
                  return parentBeanFactory.getBean(nameToLookup, requiredType);
               }
               else {
                  return (T) parentBeanFactory.getBean(nameToLookup);
               }
            }
      
            if (!typeCheckOnly) {
               markBeanAsCreated(beanName);
            }
      
            StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                  .tag("beanName", name);
            try {
               if (requiredType != null) {
                  beanCreation.tag("beanType", requiredType::toString);
               }
               RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
               checkMergedBeanDefinition(mbd, beanName, args);
      
               // Guarantee initialization of beans that the current bean depends on.
               String[] dependsOn = mbd.getDependsOn();
               
               //判断是否存在dependsOn,存在的话应该先去初始化创建dependsOn依赖的bean
               if (dependsOn != null) {
                  for (String dep : dependsOn) {
                     if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                              "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                     }
                     registerDependentBean(dep, beanName);
                     try {
                        getBean(dep);
                     }
                     catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                              "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                     }
                  }
               }
      
               // Create bean instance.
      
               //判断是否是单例的,是的话就开始创建bean
               if (mbd.isSingleton()) {
                  //纳姆达表达式 先执行getSingleton方法 ,getSingleton方法内部再执行 createBean方法
                  sharedInstance = getSingleton(beanName, () -> {
                     try {
                        return createBean(beanName, mbd, args);
                     }
                     catch (BeansException ex) {
                        // Explicitly remove instance from singleton cache: It might have been put there
                        // eagerly by the creation process, to allow for circular reference resolution.
                        // Also remove any beans that received a temporary reference to the bean.
                        destroySingleton(beanName);
                        throw ex;
                     }
                  });
                  beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
               }
      
               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);
                  }
                  beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
               }
      
               else {
                  String scopeName = mbd.getScope();
                  if (!StringUtils.hasLength(scopeName)) {
                     throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
                  }
                  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);
                        }
                     });
                     beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                  }
                  catch (IllegalStateException ex) {
                     throw new ScopeNotActiveException(beanName, scopeName, ex);
                  }
               }
            }
            catch (BeansException ex) {
               beanCreation.tag("exception", ex.getClass().toString());
               beanCreation.tag("message", String.valueOf(ex.getMessage()));
               cleanupAfterBeanCreationFailure(beanName);
               throw ex;
            }
            finally {
               beanCreation.end();
            }
         }
      
         return adaptBeanInstance(name, beanInstance, requiredType);
      }
      
      • 执行DefaultListableBeanFactory. getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法,ObjectFactory是Lambda表达式;
        1.判断当前beanName是否被排除范围中,是否正在被创建,否的话就标识为正在创建中(将beanName存入set集合中,用来解决循环依赖
        2.执行ObjectFactory.getObject()方法,会去执行lambda表达式中的方法createBean方法,去创建bean的实例对象;
        3.将beanName从当前正在创建的队列中移除,并将bean放入一级缓存singletonObjects中,并清除二级,三级缓存;
      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 + "'");
               }
               //判断当前beanName是否被排除范围中
               //判断当前beanName是否正在被创建,否的话就标识为正在创建中(循环依赖)
               beforeSingletonCreation(beanName);
               boolean newSingleton = false;
               boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
               if (recordSuppressedExceptions) {
                  this.suppressedExceptions = new LinkedHashSet<>();
               }
               try {
                  //执行纳姆达表达式中createBean方法,创建对象
                  singletonObject = singletonFactory.getObject();
                  newSingleton = true;
               }
               catch (IllegalStateException ex) {
                  // Has the singleton object implicitly appeared in the meantime ->
                  // if yes, proceed with it since the exception indicates that state.
                  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;
                  }
                  //将beanName从当前正在创建的队列中移除
                  afterSingletonCreation(beanName);
               }
               if (newSingleton) {
                  //添加到单例池中
                  addSingleton(beanName, singletonObject);
               }
            }
            return singletonObject;
         }
      }
      
      • 调用AbstractAutowireCapableBeanFactory.createBean方法去创建bean
        1.根据beanDefinition对象获取bean对应的Class对象
        2.调用doCreateBean去创建bean
      @Override
      protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
      
         if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
         }
         RootBeanDefinition mbdToUse = mbd;
      
         // Make sure bean class is actually resolved at this point, and
         // clone the bean definition in case of a dynamically resolved Class
         // which cannot be stored in the shared merged bean definition.
      
         //获取bean对应的Class对象
         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 {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            //与AOP相关
            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 {
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
               logger.trace("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);
         }
      }
      
      • 执行doCreateBean方法创建bean对象
        1.创建bean对应的包裹对象(推断实例化该bean的方法即工厂创建,supplier机制或者构造方法,反射或supplier机制创建对象),包裹对象包括bean的实例对象,以及bean对象的其他信息
        2.调用applyMergedBeanDefinitionPostProcessors方法,merge BeanDefinition后,遍历执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition方法(spring扩展点,在这完成bean是否要进行属性注入,并将注解@Autowied,@Resource属性的InjectionMetadata信息,并缓存)
        3.是否提前暴露bean工厂对象,循环依赖支撑,判断是否为单例的(spring中只有单例bean才支持循环依赖)allowCircularReferences是否支持依赖循环可以修改,当前bean是否正在被创建;提前暴露对象工厂对象ObjectFactory(lambda表达式,主要是解决依赖循环中,生成动态代理对象的,调用了 SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference方法,spring aop的实现原理之一,在这个阶段完成了依赖循环中,提前完成动态代理对象的暴露),并放入二级缓存中singletonFactories
        4.执行populateBean方法完成属性填充,遍历执行InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation方法判断该bean是否需要进行属性填充,遍历执行InstantiationAwareBeanPostProcessor. postProcessProperties方法完成注解版的属性注入,最后调用applyPropertyValues方法完成bean的自动注入
        5.执行initializeBean方法,执行bean生命周期的初始化回调,最先执行部分Aware接口的回调(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware),然后遍历执行所有BeanPostProcessor列表,执行postProcessBeforeInitialization方法回调,完成其他Aware接口的回调例如CommonAnnotationBeanPostProcessor.postProcessBeforeInitialization方法完成了@PostConstruct注解方法的回调;执行invokeInitMethods方法完成实现了InitializingBean接口的afterPropertiesSet,以及xml版本中自定义初始化方法的回调
        6.执行applyBeanPostProcessorsAfterInitialization方法,遍历执行所有BeanPostProcessor列表,执行postProcessAfterInitialization方法回调,spring aop在这步会完成代理对象的生成,先判断bean是否完成了动态代理(循环依赖,提前暴露对象),未完成就会生成动态代理对象
      protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
      
         // Instantiate the bean.
         BeanWrapper instanceWrapper = null;
         //判断是否为单例
         if (mbd.isSingleton()) {
            //移除factoryBean中的缓存
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
         }
         if (instanceWrapper == null) {
      
            //创建bean对应的包裹对象(推断创建该beand的方法,创建对象)
            instanceWrapper = createBeanInstance(beanName, mbd, args);
         }
         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 {
                  //MergedBeanDefinition 判断是否需要进行@Autowied,@Resource属性注入,
                  并缓存对应的InjectionMetadata信息
                  applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
               }
               catch (Throwable ex) {
                  throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
               }
               mbd.postProcessed = true;
            }
         }
      
         // Eagerly cache singletons to be able to resolve circular references
         // even when triggered by lifecycle interfaces like BeanFactoryAware.
      
         //循环依赖支撑,判断是否为单例的(spring中只有单例bean才支持循环依赖)allowCircularReferences 可以修改
         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
               isSingletonCurrentlyInCreation(beanName));
         if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
               logger.trace("Eagerly caching bean '" + beanName +
                     "' to allow for resolving potential circular references");
            }
            //提前暴露对象工厂对象ObjectFactory  - 并放入二级缓存中singletonFactories
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
         }
      
         // Initialize the bean instance.
         Object exposedObject = bean;
         try {
            //进行属性填充
            populateBean(beanName, mbd, instanceWrapper);
            
            //生命周期初始化回调
            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) {
      
            //earlySingletonReference  ==null  允许循环依赖 -但beanName 不存在循环依赖
            //earlySingletonReference 有值 说明存在循环依赖
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
               if (exposedObject == bean) {  //判断循环依赖时,依赖对象与在循环依赖时没有生成代理对象,在初始化回调生成的代理对象,导致对象不一致,spring会报错
                  exposedObject = earlySingletonReference;
               }
               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 " +
                           "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                  }
               }
            }
         }
      
         // Register bean as disposable.
         try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
         }
         catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
         }
      
         return exposedObject;
      }
      
  • spring是如何解决循环依赖的

    • 什么是依赖循环?
      • 在spring中,两个单例bean互相为依赖注入属性;spring默认支持依赖循环的,但可以通过allowCircularReferences关闭循环依赖;spring只支持单例bean的循环依赖,无法解决构造方法注入的循环依赖 spring-bean的依赖循环.png
    • 循环依赖源码解析

      • 先从一级缓存中singletonObjects中获取,isSingletonCurrentlyInCreation 当前bean是否正在被创建,没有的话从二级缓存中获取,在没有会从三级缓存中获取
      protected Object getSingleton(String beanName, boolean allowEarlyReference) {
         // Quick check for existing instance without full singleton lock
         //先从一级缓存中singletonObjects中获取
         Object singletonObject = this.singletonObjects.get(beanName);
         //isSingletonCurrentlyInCreation 当前bean是否正在被创建
         if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            //获取不到 再从二级缓存中获取
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
      
               synchronized (this.singletonObjects) {
                  // Consistent creation of early reference within full singleton lock
                  //双重校验 多线程
                  singletonObject = this.singletonObjects.get(beanName);
                  if (singletonObject == null) {
                     singletonObject = this.earlySingletonObjects.get(beanName);
                     if (singletonObject == null) {
                        //从3级缓存中获取,获取到的ObjectFactory
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                           singletonObject = singletonFactory.getObject();
                           this.earlySingletonObjects.put(beanName, singletonObject);
                           this.singletonFactories.remove(beanName);
                        }
                     }
                  }
               }
            }
         }
         return singletonObject;
      }
      
    • spring是怎么解决循环依赖的

      • spring是通过3个缓存Map加一个Set集合来解决循环依赖的 首先将每个正在创建的bean存放在Set singletonsCurrentlyInCreation集合当中,当支持循环依赖时,提前暴露ObjectFactory工厂对象实例,并存放在三级缓存中Map<String, ObjectFactory<?>> singletonFactories;当发生循环依赖时,由于singletonsCurrentlyInCreation存在依赖bean时,就会从三级级缓存中获取,并放入二级缓存中;当bean完成生命周期时,会将bean放入一级缓存,并清理三级缓存和一级缓存以及singletonsCurrentlyInCreation集合
    • spring中存在3个缓存map与Set集合,他们的作用是什么?

      • singletonsCurrentlyInCreation集合,存放所有当前正在实例化的beanName,主要是完成循环依赖支撑的
      • 一级缓存Map<String, Object> singletonObjects
        • 一级缓存单例池,主要存放最终形态的单例bean.注意并不是所有单例bean都存在这个缓存当中,有些特殊的单例bean不存在这个缓存当中
      • 二级缓存Map<String, Object> earlySingletonObjects
        • 二级缓存主要存放的是过渡bean,也就是从三级缓存当中产生出来的对象;他的作用是防止在多级循环依赖的情况下重复从三级缓存当中创建对象;因为三级缓存当中创建对象是需要牺牲一定得性能;有了这个缓存可以一定程度上提高效率
      • 三级缓存Map<String, ObjectFactory<?>> singletonFactories
        • 三级缓存存放的是bean工厂对象的实例, ObjectFactory能产生一个特定对象对象;程序员可以去扩展BeanPostProcessor来定制这个工厂产生对象的过程;比如AOP就是扩展了这个工厂的产生过程;从而完成完整的aop功能;如果没有这个缓存那么极端情况下会出现循环依赖注入的bean不是一个完整的bean,或者说是一个错误的bean;