Spring Boot源码简析 DefaultListableBeanFactory

相关阅读

简介

本文主要简单分析DefaultListableBeanFactorygetBean实现。

Demo

public static void main(String[] args) {
  DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
  factory.getBean("demo");
}

getBean方法由AbstractBeanFactory实现,且有多个重载实现,代码如下:

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

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return doGetBean(name, requiredType, null, false);
}

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

/**
 * @param name 待查找的Bean的名称
 * @param requiredType 用于转换查找到的Bean为指定类型
 * @param args 创建Bean实例时使用的参数,若查找的Bean不存在则需要创建
 */
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
        throws BeansException {

    return doGetBean(name, requiredType, args, false);
}

简析

getBean内部直接调用doGetBean实现,doGetBean实现较为复杂,主要逻辑如下:

  1. 根据name得到最终的BeanName,因为
    1. 传入的name可能带有&前缀(表示FactoryBean),需要除去&前缀;
    2. 传入的name可能是BeanName的别名(的别名…),需要找到BeanName;
  2. 尝试从缓存中获取已注册的单例Bean(这是解决单例循环依赖的关键);
  3. 如果缓存中存在单例Bean,且传入的args为空,那么直接从单例Bean中获取最终对象;
    1. 因为得到的Bean可能是BeanFactory,而最终想要获取的却是BeanFactory.getObject()返回的对象;
  4. 否则需要创建Bean;
    1. 如果是多例的循环依赖情况,则直接抛出异常;
    2. 如果存在父BeanFactory,且本BeanFactory中不存在该Bean的BeanDefinition,则尝试从父BeanFactory获取Bean;
    3. 校验Bean的BeanDefinition
    4. 检查dependsOn属性,确保Bean创建前该属性已被创建;
    5. 根据不同的Scope创建Bean,分为:单例、原型、其它Scope类型三种情况;
      1. 单例情况;
      2. 原型情况;
      3. 其它Scope情况;
  5. 适配Bean,如果指定了requiredType,且获取到的Bean不是requiredType类型,则需要转换Bean为指定requiredType类型;

1. 获取最终的BeanName

  1. 传入的name可能带有&前缀(表示FactoryBean),需要除去&前缀;
  2. 传入的name可能是BeanName的别名(的别名…),需要找到BeanName;
    代码如下:
// AbstractBeanFactory
String beanName = transformedBeanName(name);

protected String transformedBeanName(String name) {
    // 先是去除FactoryBean的前缀如果有的话
    // 再找到对应的BeanName如果是别名的话
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}


// BeanFactoryUtils.java
String FACTORY_BEAN_PREFIX = "&";
public static String transformedBeanName(String name) {
    Assert.notNull(name, "'name' must not be null");
    if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
        // 没有前缀标识,直接返回
        return name;
    }
    // 此处做了缓存处理,如果name已经存在(被处理过)则直接返回缓存的值,否则循环去除前缀标识,再结果缓存
    return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
        do {
            // 去除前缀标识
            beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
        }
        // 如果还存在前缀标识,则继续处理
        while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
        return beanName;
    });
}


// SimpleAliasRegistry.java
public String canonicalName(String name) {
    // 假设当前name为最终的BeanName
    String canonicalName = name;
    // Handle aliasing...
    String resolvedName;
    do {
        // 尝试获取以canonicalName为别名的BeanName
        resolvedName = this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
            // 存在,则更新最终的BeanName
            canonicalName = resolvedName;
        }
    }
    // 直到以canonicalName为别名的BeanName不存在,说明canonicalName就是最终的BeanName
    while (resolvedName != null);
    return canonicalName;
}

2. 尝试从缓存中获取已注册的单例Bean

这是解决单例循环依赖的关键,获取到的单例Bean可能正处于创建中,代码如下:

// 先尝试从缓存中获取已经注册的单例Bean
Object sharedInstance = getSingleton(beanName);

// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName) {
    // true表示支持获取早期引用,即还未完全创建的Bean
    return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 尝试从一级缓存(缓存完全创建的单例Bean)中获取beanName对应的单例Bean
    Object singletonObject = this.singletonObjects.get(beanName);
    // 如果对应的单例Bean不在一级缓存中,且处于正在创建过程中,则
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 尝试从二级缓存(缓存还未完全创建的单例Bean,即BeanFactory.getObject()的返回值)中获取beanName对应的单例Bean
        singletonObject = this.earlySingletonObjects.get(beanName);
        // 如果对应的单例Bean不在二级缓存中,且支持获取早期引用
        if (singletonObject == null && allowEarlyReference) {
            // 加锁,防止并发
            synchronized (this.singletonObjects) {
                // 再次从一级缓存中获取beanName对应的单例Bean
                singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    // 依旧不存在,则再尝试从二级缓存中获取beanName对应的单例Bean
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null) {
                        // 依旧不存在,则尝试从三级缓存(缓存创建单例Bean的ObjectFactory)中获取beanName对应的单例Bean
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            // 三级缓存中存在,则使用ObjectFactory.getObject()获取单例Bean
                            singletonObject = singletonFactory.getObject();
                            // 将ObjectFactory创建的单例Bean放入二级缓存
                            // ObjectFactory创建的单例Bean虽然创建成功,但是还未完全创建(还未属性填充、Bean后置处理等)
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            // 移除三级缓存的对应缓存,已经使用过,无需缓存了
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
        }
    }
    return singletonObject;
}

3. 从已注册的单例Bean中获取最终对象

如果缓存中存在已注册单例Bean(可能还未完全创建),且传入的args为空(这个条件值得深入思索),那么直接从单例Bean中获取最终对象;
为什么不直接返回呢?因为缓存的Bean可能是FactoryBean,而最终获取的Bean是FactoryBean.getObject()的返回;
代码如下:

if (sharedInstance != null && args == null) {
    // 缓存中存在,且未指定实例化参数
    if (logger.isTraceEnabled()) {
        // 当前Bean实例是否正在创建中
        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实例获取最终的Bean
    // 如果当前Bean实例是FactoryBean,那么需要通过其getObject获取最终的Bean如果需要的话
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}


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

    String currentlyCreatedBean = this.currentlyCreatedBean.get();
    if (currentlyCreatedBean != null) {
        registerDependentBean(beanName, currentlyCreatedBean);
    }
    // 调用父类AbstractBeanFactory的实现
    return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}


// AbstractBeanFactory.java
protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    // 如果查找的Bean是FactoryBean类型
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        if (beanInstance instanceof NullBean) {
            return beanInstance;
        }
        if (!(beanInstance instanceof FactoryBean)) {
            // 缓存的单例Bean却不是FactoryBean类型,则抛出异常
            throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
        }
        if (mbd != null) {
            // 设置BeanDefinition的isFactoryBean属性
            mbd.isFactoryBean = true;
        }
        return beanInstance;
    }

    // 查找的Bean不是FactoryBean类型
    // 缓存的单例Bean可能是FactoryBean类型,也可能不是

    if (!(beanInstance instanceof FactoryBean)) {
        // 如果缓存的单例Bean不是FactoryBean,那么可以直接返回
        return beanInstance;
    }

    // 缓存的单例Bean是FactoryBean类型
    Object object = null;
    if (mbd != null) {
        // 设置BeanDefinition的isFactoryBean属性
        mbd.isFactoryBean = true;
    }
    else {
        // 尝试从缓存中获取FactoryBean创建的Bean
        object = getCachedObjectForFactoryBean(beanName);
    }
    if (object == null) {
        // 缓存中还不存在,则需要从FactoryBean中创建

        FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
        if (mbd == null && containsBeanDefinition(beanName)) {
            // 获取FactoryBean的BeanDefinition
            mbd = getMergedLocalBeanDefinition(beanName);
        }
        // FactoryBean的BeanDefinition是否是程序本身定义的
        boolean synthetic = (mbd != null && mbd.isSynthetic());
        // 获取FactoryBean创建的Bean,且缓存创建的Bean如果可以的话
        object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    }
    return object;
}


// FactoryBeanRegistrySupport.java
protected Object getCachedObjectForFactoryBean(String beanName) {
    // 从缓存中获取FactoryBean创建的Bean
    return this.factoryBeanObjectCache.get(beanName);
}

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    // 如果FactoryBean是单例,且已经完全创建
    // 通过单例FactoryBean创建Bean,此时应该都完全创建,除非A线程在创建FactoryBean时,B线程恰好调用getBean获取其维护的Bean的行为
    // 同一线程会再次进入该方法,但此时FactoryBean会完全创建,如通过还未创建的FactoryBean获取其维护的Bean时,会先通过getSingleton(String beanName, ObjectFactory<?> singletonFactory)创建出FactoryBean,然后再进入本方法根据完全创建的FactoryBean获取其维护的Bean;
    if (factory.isSingleton() && containsSingleton(beanName)) {
        // 加锁,防止并发
        synchronized (getSingletonMutex()) {
            // 先尝试从缓存中获取FactoryBean创建的Bean
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
                // 缓存中不存在FactoryBean创建的Bean,则需要FactoryBean创建Bean
                object = doGetObjectFromFactoryBean(factory, beanName);
                // 再次尝试从缓存中获取FactoryBean创建的Bean,防止FactoryBean.getObject()的用户实现递归执行该方法时,重复对创建的Bean进行后置处理
                // 比如FactoryBean.getObject()再次调用getBean访问自身,就会递归进入该方法,而在终止递归那一层调用中,会将完全创建的Bean加入factoryBeanObjectCache缓存中,那么其他层在这里就需要判断是否已经存在完全创建好的Bean
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    // 如果缓存中存在,则表示已经经过后置处理,那么直接使用
                    // 读者可以思考这种情况是如何产生的
                    // 后续【场景分析】会提到这种情况
                    object = alreadyThere;
                }
                else {
                    // 否则需要经过后置处理如果需要的话,并且缓存

                    // 是否需要后置处理
                    if (shouldPostProcess) {
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // 如果beanName对应的单例正在创建中,则直接返回(感觉不会存在这种情况,因为进入该分支时已满足containsSingleton(beanName))
                            return object;
                        }
                        // 单例创建前处理,即缓存到表示正在创建中单例的Map,标记正在创建状态
                        beforeSingletonCreation(beanName);
                        try {
                            // Bean后置处理,Bean前置处理是在创建Bean的时候
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                    "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            // 单例创建后处理,即从表示正在创建中单例的Map移除缓存,清除正在创建状态
                            afterSingletonCreation(beanName);
                        }
                    }
                    if (containsSingleton(beanName)) {
                        // 如果Bean完全创建,则可以缓存
                        this.factoryBeanObjectCache.put(beanName, object);
                    }
                }
            }
            return object;
        }
    }
    // FactoryBean不是单例,或者FactoryBean还未完全创建
    // 如果FactoryBean不是单例,那么每次都需要重新创建Bean,且创建的Bean无需缓存,相关状态也无需标记
    // 如果FactoryBean还未完全创建,那么(大部分)会直接返回null,抛出BeanCurrentlyInCreationException异常;如果FactoryBean在创建过程中存在通过getBean获取维护的Bean的行为,递归进入该方法,那么就会出现这种异常情况
    else {
        // FactoryBean创建Bean
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        // 是否需要后置处理
        if (shouldPostProcess) {
            try {
                // Bean后置处理
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        return object;
    }
}

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 调用FactoryBean的getObject()方法创建Bean
            object = factory.getObject();
        } 
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // 不接受FactoryBean.getObject()返回null值
    // 如果FactoryBean创建的Bean为null,那么FactoryBean可能还未完成初始化:大部分的FactoryBean完成初始化前getObject()会直接返回null
    if (object == null) {
        if (isSingletonCurrentlyInCreation(beanName)) {
            // 如果FactoryBean还在创建过程中,则抛出异常
            throw new BeanCurrentlyInCreationException(
                    beanName, "FactoryBean which is currently in creation returned null from getObject");
        }
        // FactoryBean.getObject()确实返回null,那么就包装为NullBean
        object = new NullBean();
    }
    return object;
}


// DefaultSingletonBeanRegistry.java
public boolean containsSingleton(String beanName) {
    // 从一级缓存中获取缓存的单例Bean
    return this.singletonObjects.containsKey(beanName);
}

protected void beforeSingletonCreation(String beanName) {
    // 如果该BeanName需要创建检查,则缓存到正在创建单例集合中
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
        // 缓存失败,该BeanName已经被缓存,则说明已经正在创建中
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

protected void afterSingletonCreation(String beanName) {
    // 如果该BeanName需要创建检查,则从正在创建单例集合中移除
    if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
        // 移除失败,说明该BeanName并没有正在创建中
        throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
    }
}

4. 创建Bean

到这里,说明缓存中不存在单例Bean,或者传入的args有效,那么需要考虑创建Bean,代码如下:

else {
    if (isPrototypeCurrentlyInCreation(beanName)) {
        // 如果是多例的循环依赖情况,则直接抛出异常
        throw new BeanCurrentlyInCreationException(beanName);
    }

    BeanFactory parentBeanFactory = getParentBeanFactory();
    // 如果存在父`BeanFactory`,且本`BeanFactory`中不存在该Bean的`BeanDefinition`,则尝试从父`BeanFactory`获取Bean
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        String nameToLookup = originalBeanName(name);
        if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
        }
        else if (args != null) {
            return (T) parentBeanFactory.getBean(nameToLookup, args);
        }
        else if (requiredType != null) {
            return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
        else {
            return (T) parentBeanFactory.getBean(nameToLookup);
        }
    }

    if (!typeCheckOnly) {
        // 如果不是仅类型检查,则标记当前Bean为已创建状态,即将该BeanName对应的BeanDefinition缓存
        markBeanAsCreated(beanName);
    }

    StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
            .tag("beanName", name);
    try {
        if (requiredType != null) {
            beanCreation.tag("beanType", requiredType::toString);
        }
        // 获取并校验Bean的`BeanDefinition`
        RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        checkMergedBeanDefinition(mbd, beanName, args);

        // 检查dependsOn属性
        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 + "'");
                }
                // 注册dependsOn属性
                registerDependentBean(dep, beanName);
                try {
                    // 获取dependsOn属性,确保该属性在本Bean创建前已被创建
                    getBean(dep);
                }
                catch (NoSuchBeanDefinitionException ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                }
            }
        }
        // 开始创建Bean
    }
    catch (BeansException ex) {
        beanCreation.tag("exception", ex.getClass().toString());
        beanCreation.tag("message", String.valueOf(ex.getMessage()));
        cleanupAfterBeanCreationFailure(beanName);
        throw ex;
    }
    finally {
        beanCreation.end();
    }
}

protected void markBeanAsCreated(String beanName) {
    // 还未创建该beanName
    if (!this.alreadyCreated.contains(beanName)) {
        synchronized (this.mergedBeanDefinitions) {
            if (!this.alreadyCreated.contains(beanName)) {
                // 既然需要创建Bean,那么
                // 设置beanName对应的BeanDefinition的stale属性为true,表示需要重新生成
                clearMergedBeanDefinition(beanName);
                // 缓存该beanName被创建状态
                this.alreadyCreated.add(beanName);
            }
        }
    }
}

protected void cleanupAfterBeanCreationFailure(String beanName) {
    synchronized (this.mergedBeanDefinitions) {
        // 移除该beanName被创建状态
        this.alreadyCreated.remove(beanName);
    }
}

创建Bean时,还需要区分Scope类型,分为以下三种情况:

  1. 单例;
  2. 原型;
  3. 其它情况,则根据具体的Scope类型创建;

1. 原型

if (mbd.isSingleton()) {
    // 获取单例
    // 先从缓存中获取,若缓存中不存在,则通过传入的ObjectFactory的getObject()方法获取
    // 传入的ObjectFactory的getObject()方法就是直接调用createBean方法创建Bean
    sharedInstance = getSingleton(beanName, () -> {
        try {
            // 创建Bean
            return createBean(beanName, mbd, args);
        }
        catch (BeansException ex) {
            // 销毁单例Bean
            destroySingleton(beanName);
            throw ex;
        }
    });
    // 如果beanInstance是FactoryBean,那么需要通过其getObject获取最终的Bean如果需要的话
    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}


// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    // 加锁,防止并发
    synchronized (this.singletonObjects) {
        // 再次判断单例是否已经被创建
        // 这一步可以避免当指定args参数且单例Bean已经创建时,重复创建Bean
        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 + "'");
            }
            // 单例创建前处理,即缓存到表示正在创建中单例的Map,标记为正在创建状态
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 通过ObjectFactory.getObject()创建Bean,即调用createBean
                singletonObject = singletonFactory.getObject();
                // 设置新单例创建成功标识
                newSingleton = true;
            }
            catch (IllegalStateException ex) {
                // 再次判断该BeanName是否存在,如果存在则不抛出异常
                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;
                }
                // 单例创建后处理,即从表示正在创建中单例的Map移除缓存,清除正在创建状态
                afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                // 如果新单例创建成功,则缓存到单例集合中
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

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);
    }
}

public void destroySingleton(String beanName) {
    // 从缓存中移除
    removeSingleton(beanName);

    DisposableBean disposableBean;
    synchronized (this.disposableBeans) {
        disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
    }
    // 销毁Bean,如果存在的话
    destroyBean(beanName, disposableBean);
}


// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Bean实例化预处理,BeanPostProcessor的返回值(比如创建了代理)如果有效则直接退出
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            // 由于是直接退出,所以该Bean需要在resolveBeforeInstantiation中进行初始化后处理
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    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) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // Bean实例化前预处理
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // Bean存在,则进行初始化后处理
                    // 因为后续会直接返回该Bean,需要在此处进行初始化后处理
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        // 单例则尝试从缓存中获取
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        // 创建Bean
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 调用MergedBeanDefinitionPostProcessor处理
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = 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");
        }
        // 将暴露早起引用的ObjectFactory添加到三级缓存中
        // 如果在本Bean创建过程中,存在其它Bean访问(依赖)本Bean(循环依赖),就会通过ObjectFactory获取到本Bean的早期引用,见DefaultSingletonBeanRegistry.getSingleton(String beanName)方法
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    Object exposedObject = bean;
    try {
        // 填充Bean属性(这是造成循环依赖的入口)
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化Bean,包含初始化预处理和后处理,这步可能会改变exposedObject(比如存在代理)
        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) {
            // 该beanName对应的单例已经被缓存到一级或者二级缓存中,说明被其它Bean依赖,存在循环依赖
            // 从三级缓存获取到早期引用后,会将Bean移至二级缓存
            
            if (exposedObject == bean) {
                // 单例没有被改变(比如说:代理),则可以直接使用
                exposedObject = earlySingletonReference;
            }
            // 单例被改变(比如说:代理),则校验本Bean早期引用是否已被注入到其它完全创建的Bean中
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        // 存在已经完全创建的Bean注入了当前Bean的早期引用
                        actualDependentBeans.add(dependentBean);
                    }
                }
                if (!actualDependentBeans.isEmpty()) {
                    // 因为本Bean在initializeBean时被改变(比如存在代理),早期引用已经无效
                    // 所以需要抛出异常,不支持这种情况下的循环依赖
                    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.");
                }
            }
        }
    }

    // 注册销毁Bean信息
    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    // 如果存在InstantiationAwareBeanPostProcessor,则进行处理
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
            // 支持InstantiationAwareBeanPostProcessor对早期Bean引用做修改
            // Spring AOP就是实现该接口返回代理Bean
            exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
        }
    }
    return exposedObject;
}

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    ...

    // 实例化后处理,在属性设置之前
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

    // 属性设置
    // 此时会注入依赖,可能存在循环依赖,单例是通过三级缓存提前暴露创建中的Bean来规避
    ...
}

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 初始化预处理
        // 注意和applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)的区别
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 调用初始化方法进行初始化操作
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 初始化后处理
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

2. 原型

else if (mbd.isPrototype()) {
    // It's a prototype -> create a new instance.
    Object prototypeInstance = null;
    try {
        // 标记当前beanName的正在创建状态
        beforePrototypeCreation(beanName);
        // 创建Bean
        prototypeInstance = createBean(beanName, mbd, args);
    }
    finally {
        // 清除当前beanName的正在创建状态
        afterPrototypeCreation(beanName);
    }
    // 如果当前prototypeInstance是FactoryBean,那么需要通过其getObject获取最终的Bean如果需要的话
    beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

// 标记当前beanName的正在创建状态
protected void beforePrototypeCreation(String beanName) {
    Object curVal = this.prototypesCurrentlyInCreation.get();
    if (curVal == null) {
        // 不存在任何BeanName,那么直接添加当前beanName即可
        this.prototypesCurrentlyInCreation.set(beanName);
    }
    else if (curVal instanceof String) {
        // 已存在一个BeanName,则构造集合进行存储
        Set<String> beanNameSet = new HashSet<>(2);
        beanNameSet.add((String) curVal);
        beanNameSet.add(beanName);
        this.prototypesCurrentlyInCreation.set(beanNameSet);
    }
    else {
        // 已存在BeanName集合,则将当前beanName加入BeanName集合
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.add(beanName);
    }
}

// 清除当前beanName的正在创建状态
protected void afterPrototypeCreation(String beanName) {
    Object curVal = this.prototypesCurrentlyInCreation.get();
    if (curVal instanceof String) {
        // 单个beanName,即就是beanName,直接移除
        this.prototypesCurrentlyInCreation.remove();
    }
    else if (curVal instanceof Set) {
        // 多个则仅移除当前beanName
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.remove(beanName);
        if (beanNameSet.isEmpty()) {
            // 移除空集合
            this.prototypesCurrentlyInCreation.remove();
        }
    }
}

3. 其它情况,则根据具体的Scope类型创建

else {
    String scopeName = mbd.getScope();
    if (!StringUtils.hasLength(scopeName)) {
        throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
    }
    // 获取Scope类型
    Scope scope = this.scopes.get(scopeName);
    if (scope == null) {
        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    }
    try {
        // 构造ObjectFactory用于创建Bean
        Object scopedInstance = scope.get(beanName, () -> {
            // 标记当前beanName的正在创建状态
            beforePrototypeCreation(beanName);
            try {
                // 创建Bean
                return createBean(beanName, mbd, args);
            }
            finally {
                // 清除当前beanName的正在创建状态
                afterPrototypeCreation(beanName);
            }
        });
        // 如果scopedInstance是FactoryBean,那么需要通过其getObject获取最终的Bean如果需要的话
        beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    }
    catch (IllegalStateException ex) {
        throw new ScopeNotActiveException(beanName, scopeName, ex);
    }
}

5. 适配Bean

如果指定了requiredType,且获取到的Bean不是requiredType类型,则需要转换Bean为指定requiredType类型,代码如下:

return adaptBeanInstance(name, beanInstance, requiredType);

<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
    // 如果指定了类型,且得到的Bean类型不是指定的类型,那么就需要转换类型
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            // 如果存在用户指定的类型转换器则使用,否则使用默认的SimpleTypeConverter
            Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                // 转换失败,抛出异常
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            // 返回成功转换后的Bean
            return (T) 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;
}

场景分析

为了加强这一步流程的理解,准备了些测试代码,请读者分析测试代码的创建流程以及结果;
XML配置文件都一致,里面配置了待测试的Bean信息,具体如下:

<bean id="demo" class="DemoFactoryBean"></bean>

1. FactoryBean构造函数中访问自身

测试代码

public class DemoFactoryBean implements FactoryBean<Demo> {

    public static DefaultListableBeanFactory factory;

    public DemoFactoryBean() {
        factory.getBean("demo");
    }

    @Override
    public Demo getObject() throws Exception {
        return new Demo();
    }

    @Override
    public Class<?> getObjectType() {
        return Demo.class;
    }

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new XmlBeanFactory(new FileSystemResource("/path/application-bean.xml"));
        DemoFactoryBean.factory = factory;
        factory.getBean("demo");
    }
}

class Demo {
}

测试结果
报错信息如下:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demo' defined in file [/src/main/resources/application-bean.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [DemoFactoryBean]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'demo': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [DemoFactoryBean]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'demo': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:224)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1326)
    ... 8 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'demo': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at DemoFactoryBean.<init>(DemoFactoryBean.java:15)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211)

2. FactoryBean.getObject()中无限制访问自身

测试代码

public class DemoFactoryBean implements FactoryBean<Demo> {

    public static DefaultListableBeanFactory factory;

    public DemoFactoryBean() {
    }

    @Override
    public Demo getObject() throws Exception {
        return (Demo) factory.getBean("demo");
    }

    @Override
    public Class<?> getObjectType() {
        return Demo.class;
    }

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new XmlBeanFactory(new FileSystemResource("/path/application-bean.xml"));
        DemoFactoryBean.factory = factory;
        factory.getBean("demo");
    }
}

class Demo {
}

测试结果
报错信息如下:

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanCreationException
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:176)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1884)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:345)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)

3. FactoryBean.getObject()中有限制访问自身

测试代码

public class DemoFactoryBean implements FactoryBean<Demo> {

    public static DefaultListableBeanFactory factory;

    public DemoFactoryBean() {
    }

    public static int i = 3;

    @Override
    public Demo getObject() throws Exception {
        if (i-- > 0) {
            return (Demo) factory.getBean("demo");
        } else {
            return new Demo();
        }
    }

    @Override
    public Class<?> getObjectType() {
        return Demo.class;
    }

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new XmlBeanFactory(new FileSystemResource("/path/application-bean.xml"));
        DemoFactoryBean.factory = factory;
        factory.getBean("demo");
    }
}

class Demo {
}

测试结果
无报错;

4. FactoryBeanInitializingBean.afterPropertiesSet实现访问自身,不指定args参数

测试代码

public class DemoFactoryBean implements FactoryBean<Demo>, InitializingBean {

    public static DefaultListableBeanFactory factory;

    public DemoFactoryBean() {
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        factory.getBean("demo");
    }

    @Override
    public Demo getObject() throws Exception {
        return new Demo();
    }

    @Override
    public Class<?> getObjectType() {
        return Demo.class;
    }

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new XmlBeanFactory(new FileSystemResource("/path/application-bean.xml"));
        DemoFactoryBean.factory = factory;
        factory.getBean("demo");
    }
}

class Demo {
}

测试结果
无报错;

5. FactoryBeanInitializingBean.afterPropertiesSet实现访问自身,指定args参数

测试代码

public class DemoFactoryBean implements FactoryBean<Demo>, InitializingBean {

    public static DefaultListableBeanFactory factory;

    public DemoFactoryBean() {
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        factory.getBean("demo", "args");
    }

    @Override
    public Demo getObject() throws Exception {
        return new Demo();
    }

    @Override
    public Class<?> getObjectType() {
        return Demo.class;
    }

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new XmlBeanFactory(new FileSystemResource("/path/application-bean.xml"));
        DemoFactoryBean.factory = factory;
        factory.getBean("demo");
    }
}

class Demo {
}

测试结果

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demo' defined in file [/src/main/resources/application-bean.xml]: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'demo': Requested bean is currently in creation: Is there an unresolvable circular reference?
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
  at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'demo': Requested bean is currently in creation: Is there an unresolvable circular reference?
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:218)
  at DemoFactoryBean.afterPropertiesSet(DemoFactoryBean.java:19)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)

问题探索

1. 从缓存获取到单例Bean,为何只能当未指定args时才可以使用?

首先要明确的是,当单例Bean缓存存在时,即使指定args了,后续也不会再次创建单例Bean,因为DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法在创建Bean之前会再次尝试从缓存中获取单例Bean,此时获取到会直接使用;
指定args,那么创建的Bean可能不一致;
递归调用factory.getBean("demo")会使用到缓存,但递归调用factory.getBean("demo", "args")却无法用到缓存,且会抛出异常;详见【场景分析】的第4、5中情况;

2. 二级缓存就可以解决单例循环依赖问题,为什么还要引入三级缓存?

既要解决循环依赖,又不想破坏设计好的Bean生命周期管理;
Spring很好地设计了Bean的生命周期管理,但是循环依赖的存在会破坏Bean的生命周期管理;
为了解决单例循环依赖,且不想破坏Bean的生命周期管理,Spring引入了三级缓存(其实是一种惰性思想);
Spring三级缓存存储的是提供Bean早期引用的ObjectFactory,这是用于解决循环依赖;提供创建的方法而没有直接创建Bean早期引用,这是不想破坏Bean的生命周期管理;
一旦存在循坏依赖,那么三级缓存就会被使用,为了确保单例,需要将创建出来的Bean早期引用放入二级缓存,同时移除三级缓存(防止再次创建出另一个Bean的早期引用),这会破坏Bean的生命周期管理;
如果不存在循环依赖,那么三级缓存就不会被使用,Bean的生命周期管理自然也就不会被破坏;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值