Spring 源码阅读-bean的创建、循环依赖的处理以及代理

本文档基于Spring 5.1.4.RELEASE版本进行编写。

  • 下文很多地方出现默认配置,有点抽象,但大概指的就是例如:不自己编写ApplicationContext的子类、不手动注册BeanDefinition这一类的操作。
  • 下文很多地方在if判断的括号后写的注释表示的是括号内的条件怎样才会成立
  • 下文都是基于本文展示的调用链进行说明的。

关于循环依赖动态代理可以搜索补充-{0}直接跳转过去,懒得搞目录了。

在阅读过程中,如果遇到循环依赖的注释,可以先不管,在了解循环依赖时再看也不迟,有写的

1. getBean(String) & doGetBean(String, Class<T>, Object[], boolean)

getBean(String)方法负责bean的实例化以及内部参数的注入等初始化操作。

本节主要完成了dependsOn的处理,dependsOn循环依赖的处理具体见 3.1 小节。
bean的创建过程交由之后的调用链完成。

// AbstractBeanFactory
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

// AbstractBeanFactory
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    // 在本段代码中将用数字表明默认情况一个单例Bean被创建的过程

    // 1.找到最终的 beanName, 会对 FactoryBean、配置了别名的bean进行名称处理,得到最终的 beanName
    final String beanName = transformedBeanName(name);
    Object bean;

    // 2.从bean的单例缓存中获取值 (如果不为null,代表bean已经创建过/正在在创建中;但相反如果为null,不一定没创建过)
    // 在解决属性的循环依赖中发挥了重要作用
    Object sharedInstance = getSingleton(beanName);
    // 3.判断bean是否已经创建过/正在在创建中
    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 { // 进入这里时,bean可能已经在创建了
        // 如果一个bean在创建期间重复进入这里,代表出现了属性的循环依赖,见3.2小节

        // 4.判断当前原型 bean 是否正在创建中 (这个是对多例的处理)
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();

        // 5.判断有没有父容器(在示例代码中,内部IOC容器是没有父容器的,Application容器只是持有内部IOC容器)
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 有父容器且当前容器内没找到这个bean的元数据
            // 就尝试在父容器中创建bean
            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);
            }
        }

        // 6.判断typeCheckOnly是否为true (由上层调用者传入,提供的所有getBean方法传入的都是false)。
        // 如果为 true 代表获取实例是为了进行类型检查,而不是为了实际使用,
        // 有一种情况会传入true,调用AbstractBeanFactory#isTypeMatch方法,且目标bean实现了FactoryBean时。
        if (!typeCheckOnly) {
            // 7.标记bean为已创建,添加到AbstractBeanFactory的alreadyCreated集合中,并把bean的元数据删除。
            markBeanAsCreated(beanName);
        }

        try {
            // 8.获取BeanDefinition,并检查BeanDefinition是否是抽象的
            /*
            * RootBeanDefinition 这里简单说一下它跟什么有关系,<bean/>的parent属性,它在Spring有同名对应的类。
            * 我们配置的bean在被解析时,首先会被解析为GenericBeanDefinition对象实例,但是下面的getMergedLocalBeanDefinition方法调用后
            * 都会转变为RootBeanDefinition,只不过有没有parent属性决定了它们的处理逻辑的不同。
            * 可以理解为,RootBeanDefinition是一个和可能存在的parent合并而来的产物。
            * !关于<bean/>的parent属性使用示例:
            * <bean id="parent" class="com.x.x.Parent"> 如果 Parent 类里没有定义 name 属性,那么可以给标签添加 abstract=true 或者 lazy-init=true 来避免容器启动失败。
            *     <property name="name" value="foo"/>
            * </bean>
            * <bean id="child" class="com.x.x.Child" parent="parent"> Child类中必须有 name 属性才行
            *     <property name="age" value="18"/>
            * </bean>
            * Child 会继承 name 属性的值, 但是在Java代码层面2个类并没有关系,一般这情况都是用来当模板减少配置的。 
            *
            * MergedBeanDefinition 没有同名对应的类,但在getMergedLocalBeanDefinition方法中,会把转变后的RootBeanDefinition
            * 当成MergedBeanDefinition,存放到AbstractBeanFactory类的mergedBeanDefinitions属性中
            */
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            // 如果<bean abstract=true/>,而且尝试主动通过了doGetBean方法实例化,到下面这个方法就会抛出BeanIsAbstractException异常。
            // 保证了抽象的bean不可能完成实例化。
            checkMergedBeanDefinition(mbd, beanName, args);

            // 9.优先创建当前bean所依赖的bean,与<bean/>标签中的depends-on属性有关
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    // 检测双向以来,在这一步执行时,见 1.6 小节
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 每个depends-on都要注册为双向依赖关系,用于支持isDependent方法进行循环依赖检测,见 3.1 小节
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep); // 对依赖的的bean先进行处理。
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 创建bean实例
            if (mbd.isSingleton()) { // 单例
                // 10.使用传入的lambda函数创建bean (实例化 + 初始化)
                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;
                    }
                });
                // 11.如果当前bean是FactoryBean,尝试调用FactoryBean中的getObject()获取目标结果。
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            // ... 省略了多例以及其它Scope的创建方式
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // 12.保证获取的bean实例为所需的类型,如果不一致,需要通ConversionService服务转换
    // 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;
}

1.2. getSingleton(String) & getSingleton(String, boolean)

这个方法要配合属性的循环依赖来看,如果还没看到先跳过本节,关于属性的循环依赖见 3.2 小节。

/** 单例对象的缓存: Key是beanName  Value是bean对象实例. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** 早期的单例对象的缓存: Key是beanName  Value是bean对象实例. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

/** 单例的创建方式的缓存: Key是beanName  Value是一个lambda函数,代表了bean应该如何实例化. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

// DefaultSingletonBeanRegistry
public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
}

// DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 提前说明,这里的this指的就是内部IOC容器,是一个DefaultListableBeanFactory实例对象

    // 先尝试从单例缓存中读取,如果读取到了直接返回
    // 要是能读取到,代表当前bean实例已经创建完成。
    Object singletonObject = this.singletonObjects.get(beanName);

    // 如果缓存中没有,且当前的 bean 正在创建的过程中
    // 要是符合这个条件,就代表存在bean的创建过程中存在属性间的循环依赖。
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                // 如果不为空,代表allowCircularReferences为true,也就是说允许属性之间的循环依赖。
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    // 从singletonFactories晋升到earlySingletonObjects中。
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

1.3. getSingleton(String, ObjectFactory)

/** 按注册顺序存放着已经注册的单例的name */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

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

/** Names of beans currently excluded from in creation checks. */
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
        
// DefaultSingletonBeanRegistry
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) { // 缓存中没有
            // ------------------------- singletonsCurrentlyInDestruction的验证 -------------------------
        
            // 判断单例集合是否正在销毁,如果为true意味着IOC容器刷新失败,或者应用正在关闭。
            /* 
            * 在之前说过的代码中有2个地方会把这个值设置为true
            * 第1个地方:AbstractApplicationContext#refresh() 中的obtainFreshBeanFactory()逻辑里
            * 第2个地方:AbstractApplicationContext#refresh() 的catch块内调用的destroyBeans()
            */
            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 + "'");
            }
            
            // --------------------------------------- 执行单例创建前的逻辑 ---------------------------
            
            /* 如果不在 inCreationCheckExclusions 集合中,则添加到 singletonsCurrentlyInCreation 集合中,如果集合中已经存在就抛出循环依赖异常
            * singletonsCurrentlyInCreation 集合标记了当前正在创建的bean,在循环依赖的确定中发挥作用。
            * 
            * 这行代码是属性循环依赖检查的重要逻辑点,用以在不允许属性循环依赖时抛出异常,见 3.2 节。
            */
            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) {
                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;
                }
                // --------------------------------------- 执行单例创建后的逻辑 ---------------------------

                // 如果不在 inCreationCheckExclusions 集合中,则从 singletonsCurrentlyInCreation 集合中移除出去
                // 在 singletonsCurrentlyInCreation 集合中一进一出代表bean的创建完成。
                afterSingletonCreation(beanName);
            }
            // 判断是刚创建的单例对象 还是 从缓存中拿出来的
            if (newSingleton) { // 是刚创建的
                // 把刚创建的bean放到缓存对象里 并 对其他集合进行数据处理,在解决属性的循环依赖中发挥了重要作用,见 3.2 节。
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

// DefaultSingletonBeanRegistry
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 存入到单例缓存中
        this.singletonObjects.put(beanName, singletonObject);
        this.singletonFactories.remove(beanName);
        // 从早期的单例对象的缓存中移除
        this.earlySingletonObjects.remove(beanName);
        // 存入已经注册的单例
        this.registeredSingletons.add(beanName);
    }
}

1.3.1. beforeSingletonCreation & afterSingletonCreation

// DefaultSingletonBeanRegistry
protected void beforeSingletonCreation(String beanName) {
    // 如果不在 inCreationCheckExclusions 集合中,则添加到 singletonsCurrentlyInCreation 集合中
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        // 见 3.2 节
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

// DefaultSingletonBeanRegistry
protected void afterSingletonCreation(String beanName) {
    // 如果不在 inCreationCheckExclusions 集合中,则从 singletonsCurrentlyInCreation 集合中移除出去
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

1.3.2. createBean(String, RootBeanDefinition, Object[])

// 只看lambda里面
sharedInstance = getSingleton(beanName, () -> {
    try {
        return createBean(beanName, mbd, args); // 创建bean
    }
    catch (BeansException ex) {
        // 实例化过程出现异常 销毁bean实例化过程中的一切相关项
        destroySingleton(beanName);
        throw ex;
    }
});
// AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ... 日志打印  "Creating instance of bean '" + beanName + "'"
    RootBeanDefinition mbdToUse = mbd; 

    // ----------------------------------------- 解析出要实例化的Class ----------------------------------

    // 将配置文件中<bean>标签的class属性指定的符号引用加载为一个类,在一般情况下会直接把这个类放入mbd中。
    // 如果进入下面的if里面就代表不一般。
    // 如果这个过程中出现异常则会抛出 CannotLoadBeanClassException 异常。
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        /* 如果你使用了SpEL表达式配置<bean>标签的class属性,会进入这里。
        * 例如:<bean id="x" class="#{'com.example.demo.springtest.base.OutputServiceImpl'}"/>
        *
        * 针对于进入到这里的bean,其原始的BeanDefinition的beanClassName是一个表达式显然是不方便使用的
        * 这里会复制原始的BeanDefinition,并设置BeanClass,作为即将使用的RootBeanDefinition。
        */
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // --------------------------------------- 处理 MethodOverride ----------------------------------

    // Prepare method overrides.
    try {
        // 这个是对 <lookup-method/> 和 <replaced-method/> 标签的简单标记 
        // 方法内部对元数据内的 MethodOverride进行了setOverloaded(false)行为。
        // 这两个标签都会被处理成MethodOverride对象,在实例化对象时,如果有MethodOverride,会使用CGLIB生成代理类,见AbstractAutowireCapableBeanFactory#createBean。
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    // --------------------------------- 尝试靠BeanPostProcessors来生成代理类 ----------------------------

    try {
        // 给BeanPostProcessors一个返回目标类的代理实现的机会,如果返回了代理类,那就不需要再实例化bean了,见 4.1 小结
        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);
    }

    // --------------------------------------- 执行创建bean的行为 ---------------------------------------

    try {
        // 真正执行创建bean的行为
        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);
    }
}

1.3.2.1. doCreateBean(String, RootBeanDefinition, Object[])

完成bean的实例化与初始化(填充属性、调用Aware相关方法等)

// AbstractAutowireCapableBeanFactory
/** 还没有实例化完成的FactoryBean的缓存: FactoryBean name to BeanWrapper. */
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();

// 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); 
    }
    // ---------------------------------------- 实例化bean --------------------------------------
    
    // 这里是为了确认一下是不是还没有实例化结束的FactoryBean
    if (instanceWrapper == null) { // (如果)不是
        // 创建bean实例,返回的BeanWrapper包含有已经实例化的bean实例,但还没有进行属性填充
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance(); // 实例化的bean
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // ------------------------------- 应用BeanDefinitionPostProcessor ----------------------------
    
    // 调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法。
    // 对bean中使用的注解进行解析与检查(例如@Autowired、@Resource、@PostConstruct、@PreDestroy等),
    // 方便后续参数注入等合适的时机使用。
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) { // (如果)还没有被BeanDefinitionPostProcessor处理过
            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;
        }
    }

    // ---------------------------------------- 准备处理循环依赖的数据 -------------------------------------

    /*
    * 1.当前要实例化的bean是单例
    * 2.内部IOC容器允许循环引用
    *   如果内部IOC容器是非自定义的,那么总是为true的,可以手动设置。
    * 3.当前bean正在创建 (检测是否在singletonsCurrentlyInCreation集合中)
    *   在上层调用者getSingleton(String, ObjectFactory)中调用createBean之前已经把当前bean添加到了这个集合中。
    * 满足这3点就把当前bean放入到singletonFactories列表中,让程序支持bean内属性的循环引用。
    */
    // 如果当前bean是单例,默认情况下 earlySingletonExposure 的值就为 true,后面两个判断项在当前调用链中
    // 可以忽视,三个判断缩减为一个判断,也就是只要是单例这里就为true (谨慎使用这种缩减理解)。
    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");
        }
        // getEarlyBeanReference方法内部的逻辑涉及到了代理类的创建,见 4.3 小结。
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // ------------------------------------- 初始化bean实例 ----------------------------------------

    // 之前是bean的实例化工作(创建实例对象),这里是进行对bean实例进行初始化(设置属性)
    Object exposedObject = bean;
    try {
        // 填充属性
        populateBean(beanName, mbd, instanceWrapper);
        // 调用bean的InitMethods、处理bean的其他注解等
        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);
        }
    }
    
    // 到这里,当前bean的实例化与初始化工作已经完成了

    if (earlySingletonExposure) {
        // 主要目的是为了尝试从earlySingletonObjects中拿到数据
        Object earlySingletonReference = getSingleton(beanName, false);
        // 想让这个成立,可以写个Bean,里面写2+个自身的依赖的属性。
        if (earlySingletonReference != null) { // (如果)不为空
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            // 这里两者不相等,是因为在循环引用的逻辑中,BeanPostProcessor的初始化前/后的后处理可能对bean的实例发生变动。
            // 这种情况是应该尽量避免的,自定义BeanPostProcessor的逻辑时应该注意一下
            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 {
        // (有前提条件的)尝试注册到容器的disposableBeans集合中,用于在必要时执行相关的自定义销毁逻辑,下面有说明。
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
1.3.2.1.1. createBeanInstance(String, RootBeanDefinition, Object[])

这个方法的功能是:选用合适的方式创建bean实例。

// AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 上面已经调用过这个方法了,这里直接取出来RootBeanDefinition对象里的BeanClass
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // 1.类存在  2.类的访问修饰符不包含public  3.不允许非公开的访问,满足这3点就会进入 if 代码块然后报异常。
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }

    // ----------------------------------- 使用instanceSupplier实例化bean -------------------------------
    
    // 这是一种自定义实例化过程的方式,下面有使用说明,方法内部很简单不进行说明
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // ----------------------------------- 使用factory-method实例化bean ---------------------------

    // 这是一种自定义实例化过程的方式,下面有使用说明,方法内部很简单不进行说明
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // ----------------------------------- 重新创建同一bean时的快捷方式 -----------------------------
    // 使用factory-method、BeanPostProcessor机制、默认构造的首选构造函数这3种情况时,都是要解析构造函数或工厂方法的,重复的不断解析显然是性能亏损的,所以可以缓存起来下次直接使用,所计叫快捷方式。

    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            // resolvedConstructorOrFactoryMethod 和 constructorArgumentsResolved 属性的赋值在
            // ConstructorResolver的 instantiateUsingFactoryMethod 和 autowireConstructor 两个方法中都存在
            // 见 ConstructorResolver#storeCache
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            // 通过autowire构造函数实例化bean。
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 与这个方法最后一行逻辑一样。
            return instantiateBean(beanName, mbd);
        }
    }
    
    // ------------------------------ 使用BeanPostProcessor机制实例化bean ----------------------------

    // 使用BeanPostProcessor机制获取bean的构造函数,然后使用构造函数进行实例化bean。
    /* 
    * 见 AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
    * 其中对添加了@Lookup注解的方法、添加了@Autowired的构造函数有相应的处理,见下文
    */
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 1.构造函数不为null   
    // 2.AutowireMode为constructor -> 和<bean>标签的autowire属性有关
    // 3.有构造函数参数值(ConstructorArgumentValues) -> 和<bean>标签下的子标签<constructor-arg>有关
    // 4.args = null || args.length == 0  -> 本文展示的调用链的逻辑里,是一直为null的
    // 只要满足其中任意一个,就能进入if代码块
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // ----------------------------- 使用默认构造的首选构造函数实例化bean ------------------------------

    // RootBeanDefinition的这个方法会返回null
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // ----------------------------- 使用默认的方式(无参构造函数)实例化bean ------------------------------
    // 上面的那么多种形式都是特殊的实例化方式,只有这个是默认的,默认使用无参构造函数。
    
    // 如果当前bean使用了<lookup-method/> 或 <replaced-method/>,Spring会为当前bean创建CGLIB子类,并返回子类的实例化对象,而不是原始的类的。
    // 见CglibSubclassingInstantiationStrategy#instantiate(Constructor, Object[])
    return instantiateBean(beanName, mbd);
}
1.3.2.1.1.1. InstanceSupplier的使用

这个属性在BeanDefinition的多个实现类中都可以用,它提供一种仍受内部IOC容器管控的独特的实例化bean的方式。
它允许用户自定义bean的实例化逻辑,不需要再使用默认情况下通过反射去实例化bean的做法。

// 示例代码

public static void main(String[] args) {
    GenericBeanDefinition helloServiceBeanDefinition = new GenericBeanDefinition();
    helloServiceBeanDefinition.setBeanClassName("com.example.demo.springtest.base.HelloServiceImpl");
    // 自定义bean的实例化过程
    helloServiceBeanDefinition.setInstanceSupplier(() -> {
        HelloServiceImpl helloService = new HelloServiceImpl();
        helloService.setContent("自定义实例化逻辑");
        return helloService;
    });
    // 交由Spring完成内部属性的注入(DI)
    MutablePropertyValues propertyValues = helloServiceBeanDefinition.getPropertyValues();
    propertyValues.addPropertyValue("outputService", new RuntimeBeanReference("outputService"));

    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"}, true, null);
    // 这里注意,要让refresh=true,否则内部IOC容器还没有创建就注册BeanDefinition会报错
    ((BeanDefinitionRegistry) ac.getBeanFactory()).registerBeanDefinition("helloService1", helloServiceBeanDefinition);

    // bean的获取与方法调用
    HelloService helloService = ac.getBean("helloService1", HelloService.class);
    helloService.sayHello();
}
1.3.2.1.1.2. factory-method的使用

可以通过配置<bean>标签的factory-method属性来使用,它也提供一种仍受内部IOC容器管控的独特的实例化bean的方式,允许用户自定义bean的实例化逻辑。

public class ServiceFactory {
   // 非静态方法
   public XXService createService() { return new XXService(); }
   // 静态方法2
   public static XXService createStaticService2(String arg) { return new XXService(arg); }
   // 静态方法1
   public static XXService createStaticService() { return new XXService(); }
}

<!-- 非静态的方式:-->
<bean id="serviceFactory" class="a.b.c.ServiceFactory" />
<bean id="service1" factory-bean="serviceFactory" factory-method="createService"/>
<!-- 静态的方式1:  (mbd参数指定类) -->
<bean id="service2" class="a.b.c.ServiceFactory" factory-method="createStaticService"/>
<!-- 静态的方式2:  (工厂对象本身使用依赖注入配置的实例变量) -->
<bean id="service3" class="a.b.c.ServiceFactory" factory-method="createStaticService2">
    <constructor-arg value="abc"/>  <!-- 如果要传依赖对象进入 value -> ref -->
</bean>
1.3.2.1.1.3. 使用BeanPostProcessor机制获取bean的构造函数

默认情况下只会被AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors处理。

使用@Autowired注解构造函数这种情况比较罕见,当类中有多个构造函数时可以使用这个机制。
1.只有无参构造函数,返回null。
2.有无参构造函数也有有参构造函数,不使用@Autowired,返回null。
3.只有一个有参构造函数,不使用@Autowired,返回有参构造函数,但是入参有严格要求,必须是可以被容器管理的。
4.有多个有参构造函数,不使用@Autowired,返回null,之后抛出异常。
5.有任意数量构造函数,使用一个@Autowired,返回被注解的那个构造函数,入参必须是可以被容器管理的。

// 使用实例

@Service
public class TestService {
    private MessageSource messageSource;

    public TestService() {}

    @Autowired
    public TestService(MessageSource messageSource) {
        this.messageSource = messageSource;
    }
}

同时这个方法中也有对@Lookup注解的处理逻辑。
@Lookup<bean>标签的lookup-method属性是等效的。
@Lookup Annotation in Spring

public class A {
    public void test() { System.out.println(getA()); }

    public B getB() { return null; }
}

public class B() {}

<bean id="a" class="a.b.c.B" scope="prototype"/>
<bean id="b" class="a.b.c.A">
    <lookup-method name="getB" bean="a"/>
</bean>

@Test
public void testLookup() {
    A a = this.context.getBean(A.class);
    a.test();
}
1.3.2.1.2. addSingletonFactory & getEarlyBeanReference
// DefaultSingletonBeanRegistry
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    // 传入的singletonFactory是一个lambda函数,它内部的逻辑涉及到了代理类的创建,很值得注意。
    
    Assert.notNull(singletonFactory, "Singleton factory must not be null");
    synchronized (this.singletonObjects) {
        /* 这个判断如果成立,代表当前bean还没有完成实例化与初始化这整个步骤,
        * 当前方法在由createBean(String, RootBeanDefinition, Object[])产生的调用链过程内,
        * 也就是说在执行这个方法时,bean已经实例化完成了,但还没有完成赋值等后续操作。
        * 只有完成这个调用链,那么这个bean才会被放入singletonObjects中。
        */ 
        if (!this.singletonObjects.containsKey(beanName)) { // (如果)单例对象缓存中不包含当前bean
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
}

至于getEarlyBeanReference方法,它涉及到了代理类的创建,这里不进行代码展示,它的说明在下文 4.3 小节。

1.3.2.1.3. populateBean(String, RootBeanDefinition, BeanWrapper)

这个方法的功能是:向bean的实例对象内填充属性值。

// AbstractAutowireCapableBeanFactory
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // ------------------------------------------ 先行的校验 -------------------------------------------

    // 一个先行的校验,确保要被填充的的实例对象存在。(BeanWrapper持有bean实例对象)
    if (bw == null) {
        if (mbd.hasPropertyValues()) { // (如果)bean的元数据设置有属性值
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else { // 没有属性值
            // Skip property population phase for null instance.
            return;
        }
    }

    // -------------- 执行 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation -------------
    // 在(给bean实例)设置属性前,给InstantiationAwareBeanPostProcessor这个类型的BeanPostProcessor一个机会,让它们修改bean的状态。
    // 例如,这可以用来支持字段注入的方式。
    
    boolean continueWithPropertyPopulation = true;

    // 1.类不是桥接的  2.有InstantiationAwareBeanPostProcessor类型的BeanPostProcessor   满足这两点就会进入 if 代码块
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor);
                // 基于默认提供的实现,下面的if代码块不会进入。在这里就可以靠自定义BeanPostProcessor,完成自定义方式的属性的注入行为。
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false; // 标记不再需要后续的属性注入行为。
                    break;
                }
            }
        }
    }

    // 检测还是否需要继续属性注入操作
    if (!continueWithPropertyPopulation) { // 不需要
        return;
    }
    
    // bean元数据中定义的属性,和<property>标签有关,表示所有的property指定的属性。
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    // ------------------------------------- 处理<bean>标签的autowired属性 --------------------------------
    // 会根据指定的方式(byName/byType)从内部IOC容器中获取到属性的实例对象,然后再设置给BeanDefinition

    // getResolvedAutowireMode() 方法的执行结果和<bean>标签的autowired属性有关
    // 如果值为byName则代表根据名称注入;如果值为byTime则代表根据类型注入,只要满足一个条件则进入 if 代码块。
    // 默认情况下为0,也就是说不会进入 if 代码块,这个属性好像在老版本中有使用过。
    if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    // getDependencyCheck()的返回值和<bean>标签的dependency-check属性有关,高版本spring已经不允许xml配置它了。
    // 默认情况为0,也就是DEPENDENCY_CHECK_NONE,所以这里会得到false。
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); 

    // ------------------------------------- 给使用注解方式的属性注入值 ----------------------------------
    // 调用InstantiationAwareBeanPostProcessor#postProcessProperties时完成注入操作

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) { // 有InstantiationAwareBeanPostProcessor类型的Bean后处理器
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                // 对使用注解的属性进行值注入(这些值不会放到PropertyValues里),值得关注的实现类有
                // AutowiredAnnotationBeanPostProcessor -> 给@Autowired注解的属性注入值
                // CommonAnnotationBeanPostProcessor -> 给@Resource注解的属性注入值
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) { // 内部的逻辑默认情况下不会被执行。(大概这块的逻辑已经被放弃了)
                    // 在bean元数据没有配置属性时,对bean内必须注入的属性进行处理。(例如@Required注解)
                    if (filteredPds == null) {
                        /* 过滤出需要依赖检查的属性。
                        * 1.通过反射获取BeanClass的属性
                        * 2.然后去除掉 忽略的依赖关系类型 和 在忽略的依赖关系接口上存在Setter方法的属性
                        *   -前者见AbstractAutowireCapableBeanFactory中的ignoredDependencyTypes属性,
                        *   默认情况下,它是没有值的,可以手动向内部IOC容器中添加,
                        *   手动添加方式:重写refresh()中调用的postProcessBeanFactory方法,然后手动添加。
                        *  
                        *   -后者见AbstractAutowireCapableBeanFactory中的ignoredDependencyInterfaces属性,
                        *   默认情况下,它有被设置值,见refresh()中调用的prepareBeanFactory方法。
                        * 3.得到最后的结果。(如果允许缓存就缓存一下)
                        */
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    // 比较特殊的是 RequiredAnnotationBeanPostProcessor,这个类中有对@Required注解的处理
                    // 但是现在这个类和这个注解都已经弃用,默认情况下也不会被处理。
                    // 如果想要恢复使用,可以看下面给出示例。
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    
    // ------------------------------ 处理<bean>标签配置的dependency-check相关内容 ----------------------
    // 根据dependency-check指定的模式进行对参数的验证
    
    if (needsDepCheck) { // 这个代码块默认情况下也不会执行
        if (filteredPds == null) {
            // 这个方法在上面有说过,过滤出需要依赖检查的属性。
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        // 按照<bean>标签配置的dependency-check指定的模式进行验证
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    // ---------------------------------- 对PropertyValues中的属性进行注入 -------------------------------
    // 这种方式不会对使用了@Autowired、@Resource这类注解的属性进行值的注入,它们的值注入在上面就已经完成了。
    // 也就是在 ‘给使用注解方式的属性注入值’ 这一块代码内完成的。
    
    if (pvs != null) {
        // 把PropertyValues中的内容填充到bean的实例对象内。
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
1.3.2.1.3.1. 恢复@Required注解的做法
// xml配置
<bean id="helloService" class="a.b.c.HelloServiceImpl"/> // 不提供任何参数

// bean
class HelloServiceImpl implements HelloService {
    // ... 其他属性
    private OutputService outputService;
    
    //... 其他逻辑
    @Required  // 必须的的参数
    public void setOutputService(OutputService outputService) {
        this.outputService = outputService;
    }
}

// 自定义的容器实现
class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {

    public MyClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
        super(configLocations, refresh, parent);
    }

    @Override
    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 恢复@Required注解的作用
        beanFactory.addBeanPostProcessor(new RequiredAnnotationBeanPostProcessor());
        super.registerBeanPostProcessors(beanFactory);
    }
}

// 测试
@Test
public void test() {
    ApplicationContext ac = new MyClassPathXmlApplicationContext(new String[]{"spring-config.xml"}, true, null);

    HelloService helloService = ac.getBean(HelloService.class);
    helloService.sayHello();
}
1.3.2.1.3.2. 关于property属性对引用的赋值

这里不想展示完全的逻辑,很多都不用关心,主要展示一下对于RuntimeBeanReference类型参数的解析以及向对象内填充值,并且简单说明为什么默认情况下两个bean中以参数形式出现的循环依赖不会出现问题。

AbstractAutowireCapableBeanFactory#populateBean(String, RootBeanDefinition,BeanWrapper)
    AbstractAutowireCapableBeanFactory#applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues)
        BeanDefinitionValueResolver#resolveValueIfNecessary(Object, Object)
            BeanDefinitionValueResolver#resolveReference(Object, RuntimeBeanReference)
        AbstractPropertyAccessor#setPropertyValues(PropertyValues)
            AbstractPropertyAccessor#setPropertyValues(PropertyValues, boolean, boolean)
                AbstractNestablePropertyAccessor#setPropertyValue(PropertyValue)

// BeanDefinitionValueResolver
public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
    // 对应<property ref=""/>
    if (value instanceof RuntimeBeanReference) {
        RuntimeBeanReference ref = (RuntimeBeanReference) value;
        return resolveReference(argName, ref);
    }
    // .... 其他类型的属性处理
}


// BeanDefinitionValueResolver
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
    try {
        Object bean;
        String refName = ref.getBeanName();
        refName = String.valueOf(doEvaluate(refName));
        if (ref.isToParent()) {
            if (this.beanFactory.getParentBeanFactory() == null) {
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Can't resolve reference to bean '" + refName +
                        "' in parent factory: no parent factory available");
            }
            // 尝试从父容器中获取
            bean = this.beanFactory.getParentBeanFactory().getBean(refName);
        }

        else {
            // 尝试从当前容器中获取,主要就是关注这里,属性的值的获取方法。
            bean = this.beanFactory.getBean(refName);
            // 注册双向依赖关系。
            this.beanFactory.registerDependentBean(refName, this.beanName);
        }
        if (bean instanceof NullBean) {
            bean = null;
        }
        return bean;
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                this.beanDefinition.getResourceDescription(), this.beanName,
                "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
    }
}


// AbstractAutowireCapableBeanFactory
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    // ... 省略逻辑

    // Set our (possibly massaged) deep copy.
    try {
        // 通过反射,把值填充进去
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}

关于属性的循环依赖最核心的就是在这段代码里对getBean(refName)方法的调用。
关于属性的循环应用在之后会有补充,见 3.2 小节。

1.3.2.1.4 initializeBean(String, Object, RootBeanDefinition)

这个方法做了以下几件事
1.调用实现了Aware这一类接口的bean内重写的方法。
2.执行BeanPostProcessor#postProcessBeforeInitialization方法。
3.执行InitializingBeaninit-method相关的内容。
4.执行BeanPostProcessor#postProcessAfterInitialization方法

// AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // -------------------------------- 执行实现了Aware接口的bean内的相关方法 ------------------------------
    // Aware这东西太简单了不细说了,就上层向下层的主动数据传递,自己可以实现一个BeanFactoryAware测试一下。

    if (System.getSecurityManager() != null) {
        // 这个看上篇文章,里面有说 AccessController
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    // ------------------------ 执行BeanPostProcessor#postProcessBeforeInitialization方法 ----------------

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    // --------------------------------- 执行InitMethod相关的方法 --------------------------------
    /*
    * 这个东西有2种配置方式
    * 1.让bean Class实现InitializingBean接口,重写其中的方法。
    * 2.在<bean>标签中配置init-method属性。
    * 
    * 这两种的使用方法在Spring MVC框架的启动过程中说过,在正确的使用方式下,两者可以同时生效,且前者先于后者执行。
    */
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }

    // ------------------------ 执行BeanPostProcessor#postProcessAfterInitialization方法 ----------------
    
    if (mbd == null || !mbd.isSynthetic()) { 
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
1.3.2.1.5. registerDisposableBeanIfNecessary

如果需要,将当前bean注册到容器的disposableBeans集合中,用于在必要时执行相关的自定义销毁逻辑。
例如:实现了DisposableBeanAutoCloseable接口;设置了destory-method属性等,这类bean就是需要这样处理的。

// AbstractBeanFactory
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { // 单例 且 有自定义的销毁逻辑
        // 只看单例,其他的Scope不考虑
        if (mbd.isSingleton()) { // 单例
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
        else { // 其他Scope的处置
            // A bean with a custom scope...
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}

// AbstractBeanFactory
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
    // 后面那个判断的逻辑太长了,写在了下面
    // 总之,这里就是判断这个bean有没有自定义的销毁逻辑。
    return (bean.getClass() != NullBean.class &&
            (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
                    DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}

// DefaultSingletonBeanRegistry
public void registerDisposableBean(String beanName, DisposableBean bean) {
    synchronized (this.disposableBeans) {
        this.disposableBeans.put(beanName, bean);
    }
}
requiresDestruction(Object, RootBeanDefinition) 方法内的判断的逻辑格式化后的样子
(
  DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || 
  (
     hasDestructionAwareBeanPostProcessors() &&
     DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())
  )
)

先说第一个判断 DisposableBeanAdapter.hasDestroyMethod(bean, mbd) 
1.如果实现了DisposableBean或者AutoCloseable,返回true
2.如果元数据中配置了destory-method,也就是说在xml配置实现中<bean>标签里面有没有destory-method属性,没有就返回false
     2.1 如果有且值是一个正常的方法名,返回true
     2.2 如果有但值是'(inferred)',就得看类里有没有close或者shutdown方法
只要三条线任意一条为true,那第一个判断条件就是true


再说第二个判断 hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors())
3.有实现了DestructionAwareBeanPostProcessor接口的BeanPostProcessor,返回true,默认情况就有。
4.有合适的,正好能处理现在这个bean的。(DestructionAwareBeanPostProcessor接口默认情况下都会合适,就看实现类有没有重写)
     4.1 ApplicationListenerDetector  -> 如果bean实现了ApplicationListener,返回true
     4.2 InitDestroyAnnotationBeanPostProcessor -> 如果bean class内有使用了@PreDestroy注解的方法,返回true
     4.3 ScheduledAnnotationBeanPostProcessor -> 如果bean class内有使用了@Scheduled注解的方法,返回true
只有当 3 和 4中的任意1个 同时为 true 时 第二个判断条件才会为 true

第一个判断和第二个判断任意一个为true,最终结果就会为true

1.4. getObjectForBeanInstance(Object, String, String, RootBeanDefinition)

不论是哪种获取bean实例化的方式,最终都会执行到这个方法。
这个方法它是对FactoryBean类型的bean的处理,这种类型的bean实例化完成后得到的是一个工厂
使用者在使用FactoryBean时,想要的不是这个工厂,而是通过工厂内的getObject()方法自定义的逻辑创建的对象实例。
而这个方法就是用来调用FactoryBean#getObject()的,如果是单例的话,还会把执行结果缓存起来。

// AbstractAutowireCapableBeanFactory 类是实现了getObjectForBeanInstance方法的最底层的类,所以先找到 AbstractAutowireCapableBeanFactory 中的实现

// AbstractAutowireCapableBeanFactory
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");

// FactoryBeanRegistrySupport
/** 被FactoryBean创建出来的单例对象 的缓存: FactoryBean name to 单例对象. */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);

// AbstractAutowireCapableBeanFactory
protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    // ------------------------------------------------------ 存储bean之间的依赖关系 -----------------------------------------------------   

    // 获取当前已经创建的bean的名称
    // 见AbstractAutowireCapableBeanFactory#obtainFromSupplier
    String currentlyCreatedBean = this.currentlyCreatedBean.get();
    if (currentlyCreatedBean != null) {
        // 注册bean之间的双向依赖关系,用于检测循环依赖
        registerDependentBean(beanName, currentlyCreatedBean);
    }

    // 调用 AbstractBeanFactory 里面的 getObjectForBeanInstance 方法
    return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

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

    // 对于没有实现FactoryBean的bean来说,进来走个过场什么都不做就直接返回了。

    if (BeanFactoryUtils.isFactoryDereference(name)) { // bean的名称以字符&开头
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        // bean的名称以字符&开头,按照约定来说这个bean是一个FactoryBean,如果bean name以字符&开头但没有实现FactoryBean,直接抛出异常
        if (!(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
        }
    }

    // 现在我们有了bean实例,它可以是普通bean或FactoryBean。
    // 如果它是一个FactoryBean,我们就用它来创建一个bean实例,除非调用者真的想要一个对工厂的引用。
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { // 不是FactoryBean类型的bean
        return beanInstance;
    }

    Object object = null;
    if (mbd == null) {
        // 尝试从factoryBeanObjectCache这个缓存数据集中拿到数据。
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // Return bean instance from factory.
        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        // Caches object obtained from FactoryBean if it is a singleton.
        if (mbd == null && containsBeanDefinition(beanName)) {
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        boolean synthetic = (mbd != null && mbd.isSynthetic());

        // 大体步骤:
        // 1.使用 FactoryBean 中定义的 getObject() 来获取对象实例,
        // 2.根据 !synthetic 的结果,判断要不要执行所有 BeanPostProcessor的postProcessAfterInitialization 方法,为true就执行。
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}

1.5. registerDependentBean(String, String)

注册双向依赖关系。

/** 记录了bean之间的依赖关系,存储的都是beanName */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

/** 记录了bean之间的'被'依赖关系,存储的都是beanName */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

// AbstractAutowireCapableBeanFactory
public void registerDependentBean(String beanName, String dependentBeanName) {
    // 获取规范的名称,对别名的处理,最终结果是能代表这个bean的beanName
    String canonicalName = canonicalName(beanName);

    // 以A类中依赖了B为例进行说明

    // ----------------------------------------- 处理依赖关系 -------------------------------------------

    synchronized (this.dependentBeanMap) {
        // A类的名称作为Key,B类的名称作为Value记录下来,注意Value是一个集合
        Set<String> dependentBeans =
                this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
        if (!dependentBeans.add(dependentBeanName)) {
            return;
        }
    }

    // ----------------------------------------- 处理被依赖关系 -------------------------------------------

    synchronized (this.dependenciesForBeanMap) {
        // B类的名称作为Key,A类的名称作为Value记录下来,注意Value是一个集合
        Set<String> dependenciesForBean =
                this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
        dependenciesForBean.add(canonicalName);
    }
}

1.6. isDependent(String, String)

用于检查depends-on属性的循环依赖,确认传入的两个bean之间是否存在依赖关系。
要注意该方法的执行时机,以及它之后的registerDependentBean(dep, beanName)

这里结论先行,用3个示例展示这个循环依赖的执行逻辑,可以用笔在纸上画出来看看。

第一个示例:A depends-on B、B depends-on A   (A和B之间的循环依赖)
1.当首次getBean(A)时,方法的入参为(A, B),逻辑里dependentBeanMap.get(A)为null,所以执行判断2的返回语句(false),在方法外把 B->[A] 这个关系存放到dependentBeanMap中,随后调用getBean(B)。
2.当首次getBean(B)时,方法的入参为(B, A),逻辑里dependentBeanMap.get(B)获取到[A],随后在判断3的比对中发现依赖A存在于集合的返回结果中,所以执行判断3的返回语句(true),在方法外抛出循环依赖的异常。

在第一个例子中,值得注意的是执行第一步时,A是当前bean,B是A所依赖的bean,
但存入dependentBeanMap中的关系却是 B -> [A],这更像是一个假设,假设B如果依赖A的情况下会出现循环依赖。
随后在第二步的判断3中尝试判断这个假设是否成立,如果成立就代表出现循环依赖。


第二个例子:A depends-on B、B depends-on C、C depends-on A
1.当首次getBean(A)时,方法的入参为(A, B),发现dependentBeanMap里没有关于A的假设,所以执行判断2的返回语句(false),'假设B->[A]',随后调用getBean(B)。
2.当首次getBean(B)时,方法的入参为(B, C),在dependentBeanMap里发现关于B的假设 B->[A],判断3里确定当前假设不成立,然后进入下方的for循环逻辑。
  B:
    for ([A])
      if (isDependent(A, C, [B]))   因为关于A的假设还没有提出,所以判断5会得到false。
for循环的逻辑结束,最终返回false,在方法外假设C->[B],随后调用getBean(C)。
3.当首次getBean(C)时,方法的入参为(C, A),在dependentBeanMap里发现关于C的假设 C->[B],判断3里确定当前假设不成立,然后进入下方的for循环逻辑。
  C:
    for ([B])
      if (isDependent(B, C, [C])) 
  关于B的假设之前已经提出(B->[A]),但当前传入的第二个参数是C,代入判断3里发现假设不成立,随后用B的假设再次进入for循环的逻辑。
  B:
    for ([A])
      if (isDependent(A, C, [C, B]))
  因为关于A的假设还没有提出,所以判断5会得到false。
for循环的逻辑结束,最终返回false,在方法外假设A->[C],随后再次调用getBean(A)。
4.再次getBean(A)时,方法的入参为(A, B),在dependentBeanMap里发现关于A的假设 A->[C],判断3里确定当前假设不成立,然后进入下方的for循环逻辑。
  A:
    for ([C])
      if (isDependent(C, B, [A]))
  关于C的假设之前已经提出(C->[B]),当前传入的第二个参数是B,代入判断3里发现假设成立,返回true
for循环的逻辑结束,最终返回false,在方法外抛出循环依赖的异常。

在第二个例子中,值得注意的是什么?
- 现在有 A -> B -> C -> A 这样一个依赖链,从最前面的A开始执行isDependent(x, y),每次结束后都会提出一个假设 y -> x 放入到 dependentBeanMap 里。
- 判断3它做的工作就是验证这个假设是否成立,把关系图形化之后你会发现,
判断3的工作其实就是验证 当前bean 和 依赖链中上一个bean的依赖关系(例如:B和A的关系、C和B的关系),再说简单点就是相邻元素之间的依赖关系确认,能经得住判断3的验证代表相邻元素不存在循环依赖。
- 在这样一个图形化之后的关系中,你会发现似乎传入到方法里的第二个参数没有发挥作用,它发挥作用的地方是在最后for循环里,
而for循环的逻辑就有点特别了,假设当前bean是B,也就是说调用了isDependent(B, C),那for循环的逻辑就是把B之后一位的元素代入到位于B之前的所有元素的假设中进行假设判断,在当前调用链中就是让A与C确认关系。
一旦dependentBeanMap中存在了key为依赖链开头的的内容时,代表整个依赖链已经走过一遍了。


现在提出第三个例子:A depends-on B、 B depends-on C、 C depends-on D、 D depends-on A
可以得到这样一个依赖链: A -> B -> C -> D -> A。
在第二个例子中,已经掌握了循环依赖判断的基本逻辑,这里不再进行详细叙述,只是大概说明。
1.使用判断3进行相邻元素的以来确认,如果发现存在循环依赖关系直接抛出循环依赖的异常。
2.这里在第二个例子的基础上对for循环进行更详细的说明,之前说过它的逻辑是把y代入到位于x之前的所有元素的假设中进行假设判断。
以B举例,for循环的过程是这样的:isDependent(A, C, [B]) -> A还没有假设,返回false
以C举例,for循环的过程是这样的:isDependent(B, D, [C]) -> 将D带入B的假设(B->[A])中发现不成立 -> isDependent(A, D, [C, B]) -> A还没有假设,返回false
以D举例,for循环的过程是这样的:isDependent(C, A, [D]) -> 将A带入C的假设(C->[B])中发现不成立 -> isDependent(B, A, [D, C]) -> 将A带入B的假设(B->[A])中发现成立,返回true。
只要for循环的逻辑中存在任意一个使假设成立的项,那就是存在循环依赖。


如果你到这里还是不太懂for循环的逻辑,可以这么理解。
现在A、B、C、D已经系在一根直绳上了,每个元素都只知道它之前一位的是什么。那如何确定D和A相连?
只需要从D开始向前找(D->A),看A有没有出现在过这个链上,如果出现过就代表出现循环依赖。

这就是isDependent方法的逻辑,如果干看看不明白就画一下线,画一下就明白了。
// DefaultSingletonBeanRegistry
protected boolean isDependent(String beanName, String dependentBeanName) {
    synchronized (this.dependentBeanMap) {
        return isDependent(beanName, dependentBeanName, null);
    }
}

// DefaultSingletonBeanRegistry
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
    if (alreadySeen != null && alreadySeen.contains(beanName)) { // 判断1
        return false;
    }
    String canonicalName = canonicalName(beanName);
    // 注意`registerDependentBean(dep, beanName)`
    Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
    if (dependentBeans == null) { // 判断2
        return false;
    }
    // 将y带入假设看是否成立,成立就代表存在循环依赖
    if (dependentBeans.contains(dependentBeanName)) { // 判断3
        return true;
    }
    for (String transitiveDependency : dependentBeans) { // 判断4
        if (alreadySeen == null) {
            alreadySeen = new HashSet<>();
        }
        alreadySeen.add(beanName);
        if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { // 判断5
            return true;
        }
    }
    return false;
}

2. 补充-简述bean的创建过程

这里简单做个记录,简单描述一个创建步骤。

1.处理depends-on
2.创建bean
    2.1 准备MethodOverrides
    2.2 调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation (非合成才行)
    2.3 通过各种方式实例化bean(例如:构造函数、自定义lambda、工厂等方式)
    2.4 调用MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
    2.5 调用InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation (非合成才行)
    2.6 调用InstantiationAwareBeanPostProcessor#postProcessProperties
    2.7 调用InstantiationAwareBeanPostProcessor#postProcessPropertiesValues
    2.8 填充bean属性
    2.9 调用Aware相关方法
    2.10 调用BeanPostProcessor#postProcessorBeforeInitialization (非合成才行)
    2.11 调用init方法
    2.12 调用BeanPostProcessor#postProcessorAfterInitialization (非合成才行)
    2.13 尝试注册为DisposableBean
3. 类型转换

InstantiationAwareBeanPostProcessorbean实例化前后对参数发挥了作用。
BeanPostProcessorbean初始化前后发挥了作用。

3. 补充-循环依赖

Spring中有多种循环依赖情况的出现,每种循环依赖的处理方式都有所不同,这里举例几种。

3.1. depends-on导致的循环依赖

3.1.1. 触发方式

class A {
  // empty
}
class B {
  // empty
}

<bean id="a" class="a.b.c.A" depends-on="b"/>
<bean id="b" class="a.b.c.B" depends-on="a"/>

3.1.2. 会抛出的异常

Circular depends-on relationship between 'A' and 'B'

3.1.3. 解决方式

1.手动去掉标签内的depends-on属性或者类中@DependsOn注解。
2.自己实现一个ApplicationContext,在postProcessBeanFactory方法中使用BeanDefinition#setDependsOn(?)遍历修改。

源码抛出异常的位置以及检测逻辑

相关的检测逻辑位于AbstractBeanFactory#doGetBean(String, Class<T>, Object[], boolean)方法中对isDependent方法的调用处。

它的检测逻辑在上文关于isDependent方法的分析下有详细描述。
它主要依靠dependentBeanMap这个Map数据结构来实现的检测。

3.2. 属性注入阶段导致的循环依赖

3.2.1. 触发方式(方式一)

// @Autowired、@Resource注解、property属性产生的循环依赖 

@Service
class A {
    @Autowired
    B b;
}

@Service
class B {
    @Autowired
    A a;
}

@Test
public void test() {
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-config.xml"}, false, null);
    // 必须设置为false才行
    ac.setAllowCircularReferences(false);
    ac.refresh();
}

3.2.2. 触发方式(方式二)

// 使用构造函数实例化bean时受限于属性的循环依赖

@Service
class A {
  @Autowired
  public A(B b) {}
}

@Service
class B {
  @Autowired
  public B(A b) {}
}

3.2.3. 会抛出的异常

Requested bean is currently in creation: Is there an unresolvable circular reference?

3.2.4. 解决方式

对于方式一来说,如果不手动设置setAllowCircularReferences(false),是无法复现出属性注入导致的循环依赖的。
也就是说默认情况下这个值为true,如果属性出现循环依赖,Spring不会抛出任何异常,所以默认情况下压根不需要处理。

对于方式二来说,可以在其中一个构造函数的属性上添加@Lazy注解,同时在构造函数内也不能使用这个参数。

3.2.5. 源码抛出异常的位置以及检测逻辑

相关的检测逻辑位于DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)方法中对beforeSingletonCreation方法的调用处。

本例中一共列举了4种触发方式,它们都是属性注入阶段导致的循环依赖,但他们的检测逻辑不是同一部分控制的。

1.CommonAnnotationBeanPostProcessor 负责对@Resource修饰的内容进行值的注入。
2.AutowiredAnnotationBeanPostProcessor 负责对@Autowired修饰的内容进行值的注入。
3.ConstructorResolver#autowireConstructor 负责对使用构造函数进行实例化的bean进行处理。
4.AbstractAutowireCapableBeanFactory#applyPropertyValues 负责对property属性的转换与注入。

上面展示了一部分关于property属性处理的源码,那这里以property属性的循环依赖检测为例进行说明,其他的自己看吧。
它主要依靠earlySingletonObjectssingletonFactoriessingletonsCurrentlyInCreation这些数据结构来实现的检测。

举例: A类中引用B,B类中引用A

事先说明,这是对下面的格式化描述的解释
  前: 
1.xxxxx
  后:
这其中的前和后都是针对 1.xxxxx 的,注意理解

具体分析步骤:

  前: singletonsCurrentlyInCreation: 添加A
1.对A进行实例化
  后: singletonFactories: 添加A
2.对A进行属性填充
    3.解析到B的引用,调用getBean(B)
      前: singletonsCurrentlyInCreation: 添加B
    4.对B进行实例化
      后: singletonFactories: 添加B
    5.对B进行属性填充
        6.解析到A的引用,调用getBean(A)
          后: 
          earlySingletonObjects: 添加A (singletonsCurrentlyInCreation中存在A 并且 singletonFactories中存在A)
          singletonFactories: 移除A
          在getSingleton(A)方法中,在从singletonFactories中删除A之前获取到它的值作为返回值。
    7.完成B的一切工作
      后: 
      singletonsCurrentlyInCreation: 删除B
      singletonObjects: 添加B
      earlySingletonObjects: 删除B (压根就没添加过B)
      singletonFactories: 删除B
8.完成A的一切工作
  后:
  singletonsCurrentlyInCreation: 删除A
  singletonObjects: 添加A
  earlySingletonObjects: 删除A
  singletonFactories: 删除A (之前就删了)


如果按照网络上其他文章一样描述的话,可以自己替换一下
把singletonObjects看作一级缓存
把earlySingletonObjects看作二级缓存
把singletonFactories看作三级缓存

例子中可以看出来,如果依赖链长的话,逻辑其实没什么区别,主要是嵌套层次会加深而已,所以这里不进行长依赖链的分析了。

上面的分析是在默认情况下进行的(代表允许属性之间的循环依赖),一切运行正常。
那么产生了一个问题,当设置了setAllowCircularReferences(false)时,到底是哪里了发挥作用使得程序抛出循环依赖的异常?

可以结合上面的步骤看一下`AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])`方法中`earlySingletonExposure`属性的是怎么来的。

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));

很明显这第二个参数'allowCircularReferences'发挥了重要作用,它作为了起点,促使整个程序走向循环依赖异常,可以根据上面的步骤和源码进行一下分析。
首先,当'allowCircularReferences'为'false'时,Spring不会向'singletonFactories'中设置值A。
然后,很明显在上面的第6步里,因为'singletonFactories'中不存在A,所以A不会存在晋升行为,而且它也使得返回值为null。
因为返回值为null,所以Spring认为这个A还没创建,所以又跑去创建A,跟踪源码直到'DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)'里,可以看到`beforeSingletonCreation(beanName)`这么一行代码,
它里面对'!singletonsCurrentlyInCreation.add(A)'的操作会使得程序直接抛出循环依赖的异常。

补充: 
singletonsCurrentlyInCreation 实际上操作的是Map,当对Map调用add(X)时,如果Map中之前就存在X,那么最终会返回false。

singletonObjectsearlySingletonObjectssingletonFactories属性的说明。
在上面的例子中,可以很明显的看出来,singletonObjectsearlySingletonObjectssingletonFactories这3个东西是干什么的。
singletonObjects[Map]最简单,它里面存放的是创建完成的bean,它的赋值在当前bean创建完成后进行。
earlySingletonObjects[Map]比其它两个稍微复杂一点点,它里面存放的像是当前已被发现在循环依赖链中的bean(一时没想到合适的描述),稍后具体举例说明。
singletonFactories[Map]也挺简单的,它像个是否允许循环依赖功能的开关,用于辅助earlySingletonObjects的逻辑执行。
还有一个要注意的就是singletonsCurrentlyInCreation,它才是最后抛出属性循环依赖异常的守门员。

下面使对这些属性的额外补充。

对'earlySingletonObjects'这个东西的存入时机进行细致说明。

假设1: A 中属性依赖 B,B 中属性依赖 A  
把这个关系变成链状展示(简化描述): A -> B -> A     开头的A和结尾的A是同一个

默认情况下:
第一次处理A时,Spring会在'singletonsCurrentlyInCreation'和'singletonFactories'中标记A,之后发现它的属性依赖于B,会对B展开第一次处理。
第一次处理B时,Spring会在'singletonsCurrentlyInCreation'和'singletonFactories'中标记B,之后发现它的属性依赖于B,会再次对A展开处理,但Spring现在还不知道它们之间有没有循环依赖。
第二次处理A时,Spring发现'singletonsCurrentlyInCreation'中已经存在A了,也就知道'singletonsCurrentlyInCreation'集合中的项之间存在循环依赖。
到这里,实际上又回到了依赖链的开头,已经是第二次处理A了,所以'singletonFactories'内存储的A会晋升到'earlySingletonObjects'里面,来表示A出现在了循环依赖中。
而'singletonFactories'更像是个循环依赖的开关,是辅助'earlySingletonObjects'来完成逻辑处理的,一旦不允许循环依赖(使singletonFactories不工作),那么程序检查到循环依赖就会抛出异常。

假设2: A 中属性依赖 B,B 中属性依赖 C,C 中的属性依赖于 A和B
把这个关系变成链状展示(简化描述): A -> B -> C -> A, B     开头的A和结尾的A是同一个

默认情况下:
第一次处理A时,Spring会在'singletonsCurrentlyInCreation'和'singletonFactories'中标记A,之后发现它的属性依赖于B,会对B展开第一次处理。
第一次处理B时,Spring会在'singletonsCurrentlyInCreation'和'singletonFactories'中标记B,之后发现它的属性依赖于C,会对C展开第一次处理。
第一次处理C时,Spring会在'singletonsCurrentlyInCreation'和'singletonFactories'中标记C,之后发现它的属性依赖于A, B,会分别再次对A和B展开处理,但Spring现在还不知道它们之间有没有循环依赖。
第二次处理A时,Spring发现'singletonsCurrentlyInCreation'中已经存在A了,把A会晋升到'earlySingletonObjects'里面。
第二次处理B时,Spring发现'singletonsCurrentlyInCreation'中已经存在B了,把B会晋升到'earlySingletonObjects'里面。

最后这里补充一下这点:
earlySingletonObjectssingletonFactories只有一者里面可以存在当前bean。
earlySingletonObjectssingletonFactories只针对当前创建的bean(包括它的依赖链)有用。

网上还有一个这样的问题:为什么解决循环依赖使用了三级缓存?
这个问题实际上是关于属性的循环依赖的,两者都有存在的必要,在下面4.3小结有说明。
三级缓存中存放的是一个beanName到lambda函数的映射,用于

这是一些可能自己调试源码时方便理解的笔记,没啥大用,不想看就跳过。


关于property属性的循环依赖有这么几个需要关注的点:
1.`AbstractBeanFactory#doGetBean(String, Class<T>, Object[], boolean)`
    第三行`getSingleton(beanName)`

2.`DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)`
    beforeSingletonCreation(beanName)           -> (发生在bean实例化之前),把当前bean放到singletonsCurrentlyInCreation中
    afterSingletonCreation(beanName)            -> (发生在bean创建完成之后),把当前bean从singletonsCurrentlyInCreation里移除
    addSingleton(beanName, singletonObject)    -> (发生在bean创建完成之后),把当前bean放到singletonObject中 并且 从singletonFactories和earlySingletonObjects中移除当前bean

3.AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])
    两处对`earlySingletonExposure`属性的判断
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));    ->   (发生在bean实例化之后,初始化之前),把当前bean放到singletonFactories中
        getSingleton(beanName, false)         ->  (发生在bean创建完成之后),尝试从singletonObject和earlySingletonObjects中取值,实际上也拿不到值。


singletonObjects
存 -> bean的相关所有工作都完成了之后(FactoryBean除外,它需要额外操作)。 见`DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory)`的`addSingleton(beanName, singletonObject)`
删 -> 在销毁单例时(很难发生,不考虑它的删除情况)
代表含义 -> 是一个完整可用的bean实例

earlySingletonObjects
存 -> 调用getSingleton(beanName, true)时,当前bean存在于singletonFactories中
删 -> 1.bean的相关所有工作都完成了之后     2.singletonFactories存数据时

singletonFactories
存 -> 在bean实例化之后,初始化之前
删 -> 1.bean的相关所有工作都完成了之后     2.调用getSingleton(beanName, true)时,当前bean存在于singletonFactories中

4. 补充-动态代理

在bean的创建过程中,有这么几个地方会导致代理的出现,当然,前提是你配置了相关的内容,没配置的话就不会有动态代理的出现。

关于AdviceAdvisorPointcut的说明
Advice:定义的是围绕目标的一组增强行为(要织入的代码)。
PointCut:定义的是切面要织入的位置。
Advisor:负责将AdvicePointCut进行联系,指出切面应该织入的位置。

4.1. 通过BeanPostProcessors来创建bean时生成代理类

这一步是在试图使用常规方式进行实例化bean之前进行的
AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])里有这么一行代码调用resolveBeforeInstantiation,它实际上是对InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation的调用。

这里唯一需要关注的是AbstractAutoProxyCreator实现,以及它的子类AspectJAwareAdvisorAutoProxyCreator,这个类是在BeanDefinition解析aop的命名空间时注册的,在项目启动时可以观察bean注册日志找名为internalAutoProxyCreator的bean。

AspectJAwareAdvisorAutoProxyCreator类结构关系图.png

// AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    // 1. beanName为空     
    // 2. targetSourcedBeans 不包含当前beanName  (类私有的,在最初是没有值的)
    // 只要满足其中一点就可以进入 if 代码块,默认情况下都会进入
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        // 判断缓存里面是否有内容,不用想最初是没有的。
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        // 1.是否是基础实现类   
        //     只要bean class派生自 Advice、Pointcut、Advisor、AopInfrastructureBean 其中任意一种, 就会返回true
        //     如果返回true,就表示当前的类是不应该被代理的。
        // 2.是否应该跳过当前类   
        //     如果给定的bean不应该考虑由这个后处理器自动代理,子类应该重写这个方法以返回true,返回true表示应该跳过当前类。
        //     默认情况下会对.ORIGINAL结尾的类进行跳过。
        // 只要有一者为true,就会进入 if 代码块。 
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // 对于我们常规情况下自定义的bean,上面的判断是拦不住的,也就是说会执行下面的代码,但TargetSource默认情况下没有值,所以默认情况下整个方法实际上什么也没执行。

    // 这里提供了一种让使用者自定义创建代理的实现,默认是没有TargetSource实现的。
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        // 获取到类可以使用的Advisor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        // 创建代理类,这里暂时不分析
        // 4个参数分别是,bean的类,bean的名称,适用的Advisor集合、要代理的目标
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    return null;
}

关于TargetSource,文档上描述的很详细
Spring Core 文档 - 使用TargetSource实现

4.2. lookup-method或replaced-method的使用导致生成代理类

AbstractAutowireCapableBeanFactory#createBean方法里,默认情况下会使用最下方的instantiateBean(beanName, mbd)来尝试实例化bean,而且使用的是bean class的默认构造函数,但是一旦使用了
lookup-methodreplaced-method就会导致CGLIB代理类的创建。
CglibSubclassingInstantiationStrategy#instantiate(Constructor, Object[])

4.3. 填充参数时生成代理类

在之前的关于property属性对引用的赋值小结内,已经展示过bean的引用类型的属性会使用getBean(refName)来从获取容器中获取实例对象,然后注入到目标bean中。
这里要配合如下两处代码一起理解整个过程。

AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[]) 中的代码片段
(发生在bean实例化后,初始化前)
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                    "' to allow for resolving potential circular references");
        }
        // getEarlyBeanReference方法内部的逻辑涉及到了代理类的创建,很值得注意。
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

AbstractBeanFactory#doGetBean(String, Class<T>, Object[], boolean) 中的代码片段
(在填充参数时会调用到)
    Object sharedInstance = getSingleton(beanName);
在展示属性注入导致的循环依赖小结就说过'getSingleton(beanName)'的逻辑,'singletonFactories'和'earlySingletonObjects'这两个数据结构的数据来源与晋升逻辑都已经做过叙述。
在其中getSingleton(beanName)方法的调用链中会执行到这么一行代码

singletonObject = singletonFactory.getObject();

它调用的内容就是对之前添加的内容的调用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

同时也会把执行结果晋升到'earlySingletonObjects'里,所以只需要搞明白getEarlyBeanReference方法的含义就行。
// AbstractAutowireCapableBeanFactory
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 这里也是关注AbstractAutoProxyCreator类的实现
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return exposedObject;
}

// AbstractAutoProxyCreator
public Object getEarlyBeanReference(Object bean, String beanName) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (!this.earlyProxyReferences.contains(cacheKey)) {
        this.earlyProxyReferences.add(cacheKey);
    }
    return wrapIfNecessary(bean, beanName, cacheKey);
}

// AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 主要还是看下面的代码,这下面的代码核心区域和4.1小结相似

    // Create proxy if we have advice.
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理类
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

4.4. 对createProxy方法的说明

无论是4.1小结还是4.3小结,里面都有对createProxy方法的调用,这里额外写一个小结分析这个方法内的代码。

// AbstractAutoProxyCreator
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();  // 创建 ProxyFactory 实例
    proxyFactory.copyFrom(this);

    // 是否直接代理目标类以及任何接口,如果为true就是直接代理
    if (!proxyFactory.isProxyTargetClass()) { // 默认为false
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            // 会把目标类中满足下面三个条件的父接口记录下来,添加给ProxyFactory的interfaces属性,之后会用到
            // 1.没有配置回调方法的(例如:InitializingBean、DisposableBean、Closeable等)
            // 2.不是内部语言的(例如:类名不等于GroovyObject、类名不以.cglib.proxy.Factory结尾、类名不以.bytebuddy.MockAccess结尾)
            // 3.接口内方法数量大于0
            // 如果没有满足条件的接口,则会执行setProxyTargetClass(true)
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);     // 设置要代理的类
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader()); // 创建代理
}

// ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
    // createAopProxy() 方法用于确认使用哪种 AopProxy 来创建代理
    //    实际上就只提供了2中,一种是JDK形式的;另一种是CGLIB形式的
    // getProxy(classLoader) 方法很简单,只是看起来麻烦,主要就是生成代理类并返回实例对象。
    return createAopProxy().getProxy(classLoader);
}

// getProxy方法的调用链
// ProxyCreatorSupport#createAopProxy()
//   DefaultAopProxyFactory#createAopProxy(AdvisedSupport)

// DefaultAopProxyFactory
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1. 使用优化的代理策略 (默认为false)
    // 2. 目标类本身被代理而不是目标类的接口 (也就是说当前类没有ProxyInterface)
    // 3. 不存在用户自定义的ProxyInterface (上面有说是什么)
    // 满足其中一个,就会进入if代码块 (举个最简单的例子,如果目标类没有接口,则会进入if代码块,而且会使用CGLIB来进行代理)
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        // 
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        // 开发中编写的Service实现类会执行这里。
        return new JdkDynamicAopProxy(config);
    }
}

更多关于代理模式的描述和示例 -> 跳转地址
JDK Dynamic Proxy: 只能对接口进行代理
CGLIB: 不受必须实现接口的限制,但对于final方法无法代理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容