如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖

写在前面

憋了好几天了,在经历了感冒的悲伤之后,终于大脑变得清晰起来。在《聊聊Spring的IOC以及JVM的类加载》中,之前留下了一个坑,不知道大家还有没有印象。那就是一个考查源码时必然会问到的一个面试题 - -Spring循环依赖是如何解决的。今天,我们就来好好分析下这个话题,我会很细致的讲解。预计,本文会很长很长,希望大家有耐心,去读完,相信你读完之后,对于Spring的IOC部分将有更深的源码理解。采用我的逻辑去把这个问题去解读明白。大致分为以下几部分:

  • 何为循环依赖?

  • Spring管理bean对象

  • Spring如何解决循环依赖

何为循环依赖

想要理解这个问题,那么首先呢,需要有基础的知识储备。那就是Spring的IOC。IOC,是控制反转,后来出现更容易的理解 DI,依赖注入。大致上就是,一个A对象内有一个B对象属性,无需A对象显式创建B对象,可以通过Spring容器进行注入B对象到A对象中。这便是依赖注入的含义。

循环依赖的出现,是因为A对象中依赖B对象作为其中属性,B对象中依赖A对象作为其中属性。如下图所示:

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第1张图片

举个例子描述:

小明喜欢小红,小红喜欢小黑,小黑喜欢小丽,小丽喜欢小明,如果中间所有人都不放弃喜欢的人,那么每个人都将陷入爱情循环中,无法自拔。

类似于这种依赖关系,在自然界中屡见不鲜,因此,映射到我们java的对象世界中,就必然会存在。

那么,如何处理循环依赖,保证合理的程序运行,是我们需要思考的问题。Spring作为一个技术框架,必然考虑到了循环依赖的问题。

Spring管理Bean对象

理解Spring作为容器管理bean对象之前,我们可以尝试思考下,我们自主,如何实现对于依赖对象的注入

场景描述

现有一个场景,蜜蜂采蜜。蜜蜂是一个对象,蜜蜂采蜜,需要作用于花,因此依赖花的存在。

蜜蜂对象,代码如下:

public class Bee {
         /**    * 性别    */   private String sex;   /**    * 年龄    */   private Integer age;   @Autowired   private Flower flower;   /**    * 采蜜    */   public void pickingHoney() {
             // 花产蜜       flower.product();  }   public String getSex() {
             return sex;  }   public void setSex(String sex) {
             this.sex = sex;  }   public Integer getAge() {
             return age;  }   public void setAge(Integer age) {
             this.age = age;  }}

上述代码,是Spring采用注解注入的方式实现。

那么,试想,如果不使用Spring,我们如何实现呢?

一 直接简单粗暴地创建对象(可以实现,但是明显不符合自然界对象定义,因为蜜蜂不能创造出花这个对象)

public class Bee {
         /**    * 性别    */   private String sex;   /**    * 年龄    */   private Integer age;   /**    * 采蜜    */   public void pickingHoney() {
             // 花产蜜       Flower flower = new Flower();       flower.product();  }   public String getSex() {
             return sex;  }   public void setSex(String sex) {
             this.sex = sex;  }   public Integer getAge() {
             return age;  }   public void setAge(Integer age) {
             this.age = age;  }}

二 反射获取对象

   /**    * 采蜜    */   public void pickingHoney() {
            Class clazz = Class.forName("com.example.demo.test.Flower");       Flower flower = (Flower)clazz.getDeclaredConstructor().newInstance();       flower.product();  }

可见,相比第一种来说,第二种反射获取对象,很优雅的实现了对象的处理。

注:反射作为Java的一个典型技术,非常重要

上述示例代码,通过反射实现,获取类对象,然后创建类实例。且上述采用的类名形式,那么我们就可以通过配置文件读取、自定义注解等多种方式,来实现反射的实现。

有了上述的技术积累,我们可以很开心的完成第一步,反射获取对象,实现对象的注入。

再思考,在每个类对象中,处理反射逻辑,会造成代码的冗余,且会造成,对象的创建频繁,没法保证单一等问题。那么,通过学习设计模式中的单例模式、工厂模式,我们可以发现,如果应用上述设计模式,或许更优雅。就这样,我们慢慢贴近了Spring的实现。

Spring框架就是应用了各种设计模式,同时采用反射技术,来实现对象的创建、初始化等操作的。

Spring管理bean对象

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第2张图片

  • Bean对象定义方式

    Bean对象的定义,正如我们掌握的,在Spring中,可以通过几种方式完成:

    • XML文件定义

                  property>    bean>            property>    bean>beans>

      如代码展示,可以直接通过xml文件,管理bean对象,实现bean对象的定义,以及属性的注入

    • 注解形式可以通过各类注解,比如@Component @Controller @Service 等等

  • Bean对象读取

    在Spring管理下,对于Bean对象的读取,会形成一个抽象层,BeanDefinitionReader,然后形成BeanDefinition,完成对于Bean对象描述的定义

  • BeanFactory

    Bean对象的创建,由创建工程BeanFactory完成。BeanFactory会完成BeanDefinition的转换,然后构建bean对象,完成bean对象的实例化、初始化。

    工厂,通过反射技术,根据BeanDefinition创建Bean对象。

  • FactoryBean

    FactoryBean是特殊的BeanFactory

  • BeanFactoryPostPocessor

    BeanFactory的后置处理器,完成BeanFactory创建后的一系列补充

  • BeanPostPocessor

    Bean对象初始化前后的处理

流程描述:

  1. Spring读取XML文件等形式对于Bean对象的定义,构建BeanDefinition

  2. Spring的BeanFactory,读取BeanDefinition,完成Bean对象的读取,通过反射技术进行实例化

  3. BeanFactoryPostPocessor作为BeanFactory的后置处理器,完成补充处理

  4. BeanPostPocessor - before 完成对于bean对象初始化前的对象处理

  5. BeanPostPocessor - after完成对于bean对象初始化后的对象处理

  6. context.getBean 进行bean对象的使用

通过以上的分析,我们掌握了,Spring对于bean对象的读取、创建实例化、初始化的过程。了解了这些,我们才能去看循环依赖的事情。如若不然,个人觉得理解循环依赖问题,就比较困难。

Spring如何解决循环依赖

当我们能够明确了上述学习之后,我想,我们可以进入到源码的世界中去分析了。

查看解决循环依赖,也就是了解Spring是如何对Bean对象进行实例化、初始化的。

知识点:

对象的创建分为两部分,一部分为实例化,此时,在堆内存中分配了内存空间,但是未对其属性进行赋值,另一部分为初始化,完成对于实例化后对象的属性的赋值操作。因此类对象在内存空间中,两种状态,实例化状态(实例化完成、未初始化),完全状态(实例化完成、初始化完成)

一切的开始

以XML文件为例,代码如下,进入debug模式,走起,跟上队伍!

public class SpringTestApplication {
          public static void main(String[] args) {
              ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");    }}
第一站

进入到,上下文的处理构造器中,看代码,找重点。

    public ClassPathXmlApplicationContext(            String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)            throws BeansException {
              super(parent);        setConfigLocations(configLocations);        if (refresh) {
                  // 此处是我们的第一站            refresh();        }}

refresh方法,在AbstractApplicationContext内。代码内部,做了点什么事情呢,可以详细的看看代码注释。

    public void refresh() throws BeansException, IllegalStateException {
              synchronized (this.startupShutdownMonitor) {
                  // 完成准备,设置时间啊等等,我们无需太关心            prepareRefresh();            // 无需多关心            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            // bean factory 创建前的准备阶段,对应我们上述图的流程            prepareBeanFactory(beanFactory);            try {
                      //BeanFactory的处理过程,跟我们的对象创建关系不大 开始                // Allows post-processing of the bean factory in context subclasses.                postProcessBeanFactory(beanFactory);                // Invoke factory processors registered as beans in the context.                invokeBeanFactoryPostProcessors(beanFactory);                // Register bean processors that intercept bean creation.                registerBeanPostProcessors(beanFactory);                // Initialize message source for this context.                initMessageSource();                // Initialize event multicaster for this context.                initApplicationEventMulticaster();                // Initialize other special beans in specific context subclasses.                onRefresh();                // Check for listener beans and register them.                registerListeners();                //BeanFactory的处理过程,跟我们的对象创建关系不大 完成                // Instantiate all remaining (non-lazy-init) singletons.                //实例化,所有的非懒加载的单例bean对象,可见第二站入口来了,开启                finishBeanFactoryInitialization(beanFactory);                // Last step: publish corresponding event.                finishRefresh();            }            catch (BeansException ex) {
                      if (logger.isWarnEnabled()) {
                          logger.warn("Exception encountered during context initialization - " +                            "cancelling refresh attempt: " + ex);                }                // Destroy already created singletons to avoid dangling resources.                destroyBeans();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }            finally {
                      // Reset common introspection caches in Spring's core, since we                // might not ever need metadata for singleton beans anymore...                resetCommonCaches();            }        }}
第二站,真正的入口

看这个前,我们有必要了解一个类对象,其中提供了三个缓存对象

DefaultSingletonBeanRegistry

    /** Cache of singleton objects: bean name to bean instance. */    // 一级缓存    private final Map singletonObjects = new ConcurrentHashMap<>(256);    /** Cache of singleton factories: bean name to ObjectFactory. */    // 三级缓存    private final Map> singletonFactories = new HashMap<>(16);    /** Cache of early singleton objects: bean name to bean instance. */    // 二级缓存    private final Map earlySingletonObjects = new HashMap<>(16);

记住,对应的对象名,后续在源码中会依次出现。

回到第二站,查看相关源码,直接查看注释中中文标记点,继续追踪

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
              // Initialize conversion service for this context.        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 bean post-processor        // (such as a PropertyPlaceholderConfigurer bean) registered any before:        // at this point, primarily for resolution in annotation attribute values.        if (!beanFactory.hasEmbeddedValueResolver()) {
                  beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));        }        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.        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.        beanFactory.freezeConfiguration();        // Instantiate all remaining (non-lazy-init) singletons.        // 实例化,所有的非懒加载的单例bean对象        beanFactory.preInstantiateSingletons();}

DefaultListableBeanFactory

    @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.        List beanNames = new ArrayList<>(this.beanDefinitionNames);        // Trigger initialization of all non-lazy singleton beans...        // 根据BeanDefinition 获取bean定义信息        for (String beanName : beanNames) {
                  RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            // 首先 A对象 此处非抽象类 单例 非懒加载才能进入,A对象符合条件,进入            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                      if (isFactoryBean(beanName)) {
                          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)                                            ((SmartFactoryBean>) factory)::isEagerInit,                                    getAccessControlContext());                        }                        else {
                                  isEagerInit = (factory instanceof SmartFactoryBean &&                                    ((SmartFactoryBean>) factory).isEagerInit());                        }                        if (isEagerInit) {
                                  getBean(beanName);                        }                    }                }                else {
                          //A对象 进入                    getBean(beanName);                }            }        }        // 省略}

AbstractBeanFactory

    @Override    public Object getBean(String name) throws BeansException {
              // Spring源码内 do开头,都是真正做事情的方法        return doGetBean(name, null, null, false);}
第三站 创建bean

AbstractBeanFactory

查看中文代码注释部分,快速定位。按照代码执行序号,查看逻辑。

protected  T doGetBean(final String name, @Nullable final Class requiredType,      @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
          final String beanName = transformedBeanName(name);    Object bean;    // Eagerly check singleton cache for manually registered singletons.      // 1. 获取单例bean对象 第四站入口    Object sharedInstance = getSingleton(beanName);      // 根据第四站代码分析,此时A对象为空,返回空,将继续执行    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 + "'");        }      }      bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);    }    else {
            // Fail if we're already creating this bean instance:      // We're assumably within a circular reference.      if (isPrototypeCurrentlyInCreation(beanName)) {
              throw new BeanCurrentlyInCreationException(beanName);      }      // Check if bean definition exists in this factory.      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);      }      try {
              final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);        checkMergedBeanDefinition(mbd, beanName, args);        // Guarantee initialization of beans that the current bean depends on.        String[] dependsOn = mbd.getDependsOn();        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.                // 3. 创建对象        if (mbd.isSingleton()) {
                          // 进入方法          sharedInstance = getSingleton(beanName, () -> {
                  try {
                                  // 5. 创建对象 实现A 对象实例              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;            }          });          bean = 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);          }          bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);        }        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.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +              ClassUtils.getQualifiedName(requiredType) + "'", ex);        }        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());      }    }      // 返回    return (T) bean;  }
第四站

DefaultSingletonBeanRegistry

    @Nullable    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
              // 2.        // 一级缓存中查找,是否存在bean A对象,此时为空        Object singletonObject = this.singletonObjects.get(beanName);        // 判断一级缓存为空并且是否在创建中,我们在知识点中提及,类对象两种状态,实例化、完全状态,此时均未发生,因此不会进入判断        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                  synchronized (this.singletonObjects) {
                      singletonObject = this.earlySingletonObjects.get(beanName);                if (singletonObject == null && allowEarlyReference) {
                          ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);                    if (singletonFactory != null) {
                              singletonObject = singletonFactory.getObject();                        this.earlySingletonObjects.put(beanName, singletonObject);                        this.singletonFactories.remove(beanName);                    }                }            }        }        // 直接返回 空对象        return singletonObject;}
    public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
              Assert.notNull(beanName, "Bean name must not be null");        // 4. 执行对象处理        synchronized (this.singletonObjects) {
                  // 一级缓存中获取A 对象,无            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 + "'");                }                beforeSingletonCreation(beanName);                boolean newSingleton = false;                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);                if (recordSuppressedExceptions) {
                          this.suppressedExceptions = new LinkedHashSet<>();                }                try {
                          // 获取对象 ObjectFactory> 通过匿名内部类执行,匿名内部类 ,获取到A实例化对象,此时A 为实例化状态,创建中                    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;                    }                    afterSingletonCreation(beanName);                }                if (newSingleton) {
                          addSingleton(beanName, singletonObject);                }            }            return singletonObject;        }}
  1. 执行匿名内部类 创建A 对象

AbstractAutowireCapableBeanFactory

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)            throws BeanCreationException {
              // Instantiate the bean.        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {
                  instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        if (instanceWrapper == null) {
                  //实例A创建            instanceWrapper = createBeanInstance(beanName, mbd, args);        }        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 {
                          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.        // 此处 A对象已创建,会进入判断        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");            }            //三级缓存,放入实例化对象A 此时A 未完全状态 缓存内状态,见代码下图示            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));        }        // Initialize the bean instance.        Object exposedObject = bean;        try {
                  // 6. 填充bean            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) {
                  Object earlySingletonReference = getSingleton(beanName, false);            if (earlySingletonReference != null) {
                      if (exposedObject == bean) {
                          exposedObject = earlySingletonReference;                }                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                          String[] dependentBeans = getDependentBeans(beanName);                    Set 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如何解决循环依赖_第3张图片

  1. 填充bean属性内容

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
              // 省略        if (pvs != null) {
                  //处理属性内容            applyPropertyValues(beanName, mbd, bw, pvs);        }}
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
              // 省略代码        // Create a deep copy, resolving any references for values.        List deepCopy = new ArrayList<>(original.size());        boolean resolveNecessary = false;        for (PropertyValue pv : original) {
                  if (pv.isConverted()) {
                      deepCopy.add(pv);            }            else {
                      // B对象                String propertyName = pv.getName();                // 值为 null                Object originalValue = pv.getValue();                if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                          Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();                    if (writeMethod == null) {
                              throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);                    }                    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);                }                // 7. 解决B对象                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);                Object convertedValue = resolvedValue;                //省略代码}

BeanDefinitionValueResolver

@Nullable    public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
              // We must check each value to see whether it requires a runtime reference        // to another bean to be resolved.        if (value instanceof RuntimeBeanReference) {
                  RuntimeBeanReference ref = (RuntimeBeanReference) value;            //B对象作为A对象属性值,类型为RuntimeBeanReference 进入判断,执行方法resolveReference            return resolveReference(argName, ref);        }        // 省略代码
@Nullable    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
              try {
                  Object bean;            Class> beanType = ref.getBeanType();            if (ref.isToParent()) {
                      BeanFactory parent = this.beanFactory.getParentBeanFactory();                if (parent == null) {
                          throw new BeanCreationException(                            this.beanDefinition.getResourceDescription(), this.beanName,                            "Cannot resolve reference to bean " + ref +                                    " in parent factory: no parent factory available");                }                if (beanType != null) {
                          bean = parent.getBean(beanType);                }                else {
                          // A对象依赖B对象,获取B对象                    bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));                }            }            //省略代码

开始B对象的获取

第五站 依赖对象 B生成

重新回到

protected  T doGetBean(final String name, @Nullable final Class requiredType,            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
              final String beanName = transformedBeanName(name);        Object bean;        // Eagerly check singleton cache for manually registered singletons.        //进入获取        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 + "'");                }            }            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);        }    //省略代码

类似A对象的处理,此处忽略

最终到了,处理B对象属性A对象,上述描述6 。此时,缓存情况如下:

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第4张图片

进一步补充属性,即完成B对象中属性A对象的获取。

重新进入doGetBean ,进入 getSingleton

    @Nullable    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
              // 此时一级缓存中获取A对象,同样 A对象为空,此时一级缓存中不存在        Object singletonObject = this.singletonObjects.get(beanName);        // A对象状态为 实例化 因此,在创建中,进入判断        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                  synchronized (this.singletonObjects) {
                                      // 二级缓存中获取 A对象 ,A对象为空,进入判断                singletonObject = this.earlySingletonObjects.get(beanName);                if (singletonObject == null && allowEarlyReference) {
                          //三级缓存中获取 A对象,可以读取到值                    ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);                    if (singletonFactory != null) {
                              singletonObject = singletonFactory.getObject();                        // 将A 对象放入 二级缓存                        this.earlySingletonObjects.put(beanName, singletonObject);                        // 将A 对象从三级缓存中删除                        this.singletonFactories.remove(beanName);                    }                }            }        }        return singletonObject;}

此时,缓存情况如下:

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第5张图片

处理完B对象的属性A对象后,B对象此时变为初始化完成、实例化完成,成为完全态

    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 + "'");                }                beforeSingletonCreation(beanName);                boolean newSingleton = false;                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);                if (recordSuppressedExceptions) {
                          this.suppressedExceptions = new LinkedHashSet<>();                }                try {
                          //                    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;                    }                    afterSingletonCreation(beanName);                }                if (newSingleton) {
                          // 8. A对象属性对象 B对象完成初始化后执行                    addSingleton(beanName, singletonObject);                }            }            return singletonObject;        }}
    protected void addSingleton(String beanName, Object singletonObject) {
              synchronized (this.singletonObjects) {
                  // 一级缓存放入 B对象 完全态            this.singletonObjects.put(beanName, singletonObject);            // 三级缓存删除 B对象            this.singletonFactories.remove(beanName);            // 二级缓存删除 B对象            this.earlySingletonObjects.remove(beanName);            this.registeredSingletons.add(beanName);        }}

此时,缓存情况如下:

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第6张图片

此时A对象中属性B对象,完成初始化,A对象会执行以下代码

    protected void addSingleton(String beanName, Object singletonObject) {
              synchronized (this.singletonObjects) {
                  // 一级缓存放入 A对象 完全态            this.singletonObjects.put(beanName, singletonObject);            // 三级缓存删除 A对象            this.singletonFactories.remove(beanName);            // 二级缓存删除 A对象            this.earlySingletonObjects.remove(beanName);            this.registeredSingletons.add(beanName);        }}

此时,缓存情况如下:

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第7张图片

第六站 遍历Bean对象 B
@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.        List beanNames = new ArrayList<>(this.beanDefinitionNames);        // Trigger initialization of all non-lazy singleton beans...        // 根据BeanDefinition 获取bean定义信息        for (String beanName : beanNames) {
                  RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);            // 首先 A对象 此处非抽象类 单例 非懒加载才能进入,A对象符合条件,进入            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                      if (isFactoryBean(beanName)) {
                          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)                                            ((SmartFactoryBean>) factory)::isEagerInit,                                    getAccessControlContext());                        }                        else {
                                  isEagerInit = (factory instanceof SmartFactoryBean &&                                    ((SmartFactoryBean>) factory).isEagerInit());                        }                        if (isEagerInit) {
                                  getBean(beanName);                        }                    }                }                else {
                          //B对象 进入                    getBean(beanName);                }            }        }        // 省略}
故事结尾

最后直接返回,因为完全态在一级缓存中都存在了。

    @Nullable    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
              // 从一级缓存中获取B对象,获取得到,直接返回        Object singletonObject = this.singletonObjects.get(beanName);        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                  synchronized (this.singletonObjects) {
                      singletonObject = this.earlySingletonObjects.get(beanName);                if (singletonObject == null && allowEarlyReference) {
                          ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);                    if (singletonFactory != null) {
                              singletonObject = singletonFactory.getObject();                        this.earlySingletonObjects.put(beanName, singletonObject);                        this.singletonFactories.remove(beanName);                    }                }            }        }        return singletonObject;}

终于结束了,带着大家走了一遍源码,不知道你能理解多少。

从以上源码,我们可以看到,Spring采用三级缓存,来实现循环依赖的解决。

常见的面试问题

  • 循环依赖必须使用三级缓存么

    其实,从我们解读看来,只需要把对象的两个状态处理好,就能处理好循环依赖的问题,因此实际上来说,不必要使用三级缓存对于一般的bean对象来讲。

  • 为何Spring解决三级缓存要使用三级缓存,而不是二级缓存

    为何Spring采用三级缓存,其实主要是因为Bean对象不仅仅是基础的一般对象,还会有一些AOP后期增强对象,通过Cglib或者JDK动态代理手段,织入的对象。二级缓存,只能满足一般Bean对象的处理,无法处理更多的对象。

    再看三级缓存

        /** Cache of singleton objects: bean name to bean instance. */    // 一级缓存    private final Map singletonObjects = new ConcurrentHashMap<>(256);    /** Cache of singleton factories: bean name to ObjectFactory. */    // 三级缓存 返回值类型 泛型为 ObjectFactory> 能够处理更多的事项    private final Map> singletonFactories = new HashMap<>(16);    /** Cache of early singleton objects: bean name to bean instance. */    // 二级缓存    private final Map earlySingletonObjects = new HashMap<>(16);

    以上就比较明确,为何使用三级而不是二级了

总结

看源码就是需要细致认真的解读,因此需要耐心。希望读着也能有耐心看下去。如果你可以,我相信,你对于循环依赖,不会有什么难点。

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第8张图片

如何更改spring源码_最强源码分析,带你一步步弄清楚Spring如何解决循环依赖_第9张图片

你可能感兴趣的:(如何更改spring源码)