美文网首页
Spring源码解析(七)-获取单例bean

Spring源码解析(七)-获取单例bean

作者: 秋水畏寒 | 来源:发表于2020-05-24 22:33 被阅读0次

Spring版本

5.2.5.RELEASE

参考

Spring IOC 容器源码分析 - 获取单例 bean

源码解析

1. BeanFactory#getBean(String name)

应用初始化容器的时候,bean并不会马上被加载(除非显式指定lazyinit = false),而是在调用getBean的时候才会被加载,下面我们就来看看getBean的具体实现

getBean方法实际上是交由doGetBean实现的:

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

查看doGetBean方法:

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                              @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

        // 已注册的bean会以<beanName,bean>的形式缓存在一个map
        // 1、由于BeanFactory本身也是一个bean,当请求是BeanFactory这个bean的时候,name是带有&符号的,而缓存map里面的beanName都是不带&符号的
        // 2、name也有可能是bean的一个别名
        // transformedBeanName方法便是将以上俩种可能的name转化为具体的beanName
        final String beanName = transformedBeanName(name);
        Object bean;

        // Eagerly check singleton cache for manually registered singletons.
        // 从缓存map中获取bean
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                }
                else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // 这里面对sharedInstance做了一些处理,分为以下几种情况:
            // 1、如果name是以&符号开头(代表想要获取的是FactoryBean),
            // 但是sharedInstance是NullBean,或者sharedInstance根本不是一个FactoryBean,
            // 那么此时返回一个NullBean,或者抛出异常
            // 2、如果sharedInstance是一个普通bean,或者name是以&开头,代表想要获取FactoryBean本身,此时直接返回
            // 3、其他情况下,调用getObject方法获取真正的bean实例
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }

        else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // BeanFactory 无法处理Prototype类型的bean的循环依赖问题
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // Check if bean definition exists in this factory.
            // 获取父BeanFactory
            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 父BeanFactory不为空且<beanName,beanDefinition>的map中不含有该beanName(也就是说该bean对应的BeanDefinition还未进行解析),那么将获取bean实例委托给父BeanFactory
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                // 将可能是别名的name解析成具体的beanName,如果name以&开头,那么返回值也将带有&符号
                String nameToLookup = originalBeanName(name);
                // 如果是AbstractBeanFactory类型,递归调用doGetBean方法
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {
                    // Delegation to parent with explicit args.
                    // 如果参数不为空,调用接口层次的getBean,由getBean决定具体的实现方法
                    // (getBean是一个通用接口声明,具体有多中实现,包含但不止AbstractBeanFactory)
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else {
                    // No args -> delegate to standard getBean method.
                    // 参数为空,与参数不为空逻辑一致,只不过交由getBean的另外一个重载方法去处理
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }

            // typeCheckOnly
            // true表示doGetBean仅仅是为了做类型检查
            // false表示为了实际使用bean实例,如果是实际使用bean实例,则有必要标识为已创建,以让缓存起到作用
            if (!typeCheckOnly) {
                // 将beanName加入到alreadyCreated集合中,标识为已创建,并且将beanDefinition的stale属性设置为true,防止创建期间元数据发生变更
                markBeanAsCreated(beanName);
            }

            try {
                // 将父bean和子bean合并,可能是从缓存中获取
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 检查mbd是否是抽象,若是,抛出异常
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                // 保证bean下的depends on已经实例化
                // 注意depends on和循环依赖的区别
                // <bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
                //     <property name="manager" ref="manager" />
                // </bean>
                // 使用@Autowired的时候,我们注入的是property
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 不允许循环depends on
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        // 注册depends on关系,注册之后其他bean创建的时候才能通过isDependent方法检查循环depends on
                        registerDependentBean(dep, beanName);
                        try {
                            // 创建depend on实例
                            getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // Create bean instance.
                if (mbd.isSingleton()) {
                    // 创建单例类型的bean实例
                    // getSingleton方法后面解析
                    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.
                            // 在早期的创建过程中,可能为了解决循环引用问题,导致beanName加入了singleton缓存中,此时需要移除该缓存
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    // 创建prototype类型的bean实例
                    Object prototypeInstance = null;
                    try {
                        // 写入prototype类型的依赖关系,以便上述的isPrototypeCurrentlyInCreation方法做出拦截
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        // 创建完毕则可以删除prototype类型的依赖关系
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else {
                    // 创建其他类型的bean实例
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                        "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            }
            catch (BeansException ex) {
                // 创建失败的情况下删除缓存数据
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // Check if required type matches the type of the actual bean instance.
        // 检查创建出来的bean实例是否是要求的类型
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                // 不是的情况下,进行类型装换
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

方法很长,总结起来主要做了以下几点:

  • 通过transformedBeanName做了beanName的转换
  • 从缓存中获取bean实例
    • 缓存不为空,通过getObjectForBeanInstance获取bean实例
    • 缓存为空,创建bean
  • 将获取到的bean实例与requiredType做校验,必要时进行类型转换

下面逐个解析


2. 转换beanName

方法一开始传进来的beanName可能有以下俩种情况:

  • 以&开头的name,代表获取FactoryBean这个bean
  • 别名

而<beanName,bean>的缓存中,beanName是不带&符号的非别名beanName,这时候需要将beanName转化为真正的beanName,方便后面再缓存中获取beanName对应的bean:

    protected String transformedBeanName(String name) {
        return canonicalName(BeanFactoryUtils.transformedBeanName(name));
    }

通过别名获取到真正的beanName:

    public String canonicalName(String name) {
        String canonicalName = name;
        // Handle aliasing...
        String resolvedName;
        do {
            resolvedName = this.aliasMap.get(canonicalName);
            if (resolvedName != null) {
                canonicalName = resolvedName;
            }
        }
        while (resolvedName != null);
        return canonicalName;
    }

对name做去除&符号的处理:

    public static String transformedBeanName(String name) {
        Assert.notNull(name, "'name' must not be null");
        // 如果name不是以&开头,直接返回
        if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
            return name;
        }
        // 否则,从transformedBeanNameCache中获取name对应的value,如果value为空,对beanName剔除&前缀,之后写入transformedBeanNameCache
        return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
            do {
                beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
            }
            while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
            return beanName;
        });
    }

其中,Map#computeIfAbsent定义如下:

default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction)

含义是如果map中的key对应的value为空,那么使用mappingFunction生产一个值,作为value,并写入map中


3. AbstractBeanFactory#getSingleton

    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 从缓存中读取beanName对应的bean
        Object singletonObject = this.singletonObjects.get(beanName);
        // 如果不存在该beanName对应的bean,并且该bean处于创建之中(由于循环依赖导致beanName被写入singletonsCurrentlyInCreation),那么通过早期引用来解决循环依赖问题
        // 写入singletonsCurrentlyInCreation这一步发生在AbstractBeanFactory#doGetBean#createBean#doCreateBean#populateBean#applyPropertyValues
        // #resolveValueIfNecessary#resolveInnerBean#getObjectFromFactoryBean#beforeSingletonCreation
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                // 从早期引用中获取bean
                singletonObject = this.earlySingletonObjects.get(beanName);
                // 早期引用不存在bean且允许使用早期引用
                if (singletonObject == null && allowEarlyReference) {
                    // 获取bean创建工厂
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 调用getObject方法创建bean
                        singletonObject = singletonFactory.getObject();
                        // 写入早期引用,解决循环依赖问题
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        // 移除工厂
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return singletonObject;
    }

从缓存中获取bean,这里涉及到了循环依赖的处理,大致就是如果碰到当前获取的bean处于正在创建中:

isSingletonCurrentlyInCreation

那么说明当前bean已经处于循环依赖中,那么写入earlySingletonObjects中,那么下次进来,就可以直接返回对应实例,从而解决早期引用问题。

举例来说,A依赖B,B依赖A,首先创建A,将A写入正在创建的bean集合isSingletonCurrentlyInCreation中,然后发现依赖B,接着去创建B,发现依赖A,这时发现A处于isSingletonCurrentlyInCreation中,那么将A写入早期引用集合earlySingletonObjects中,然后完成创建B流程,接着也就完成创建A流程


4. AbstractBeanFactory#getObjectForBeanInstance

查看源码之前,有个疑问,既然已经从缓存中获取到了实例,如果还要通过getObjectForBeanInstance进行处理?这是因为从缓存中获取到实例是最原始的实例,如果通过getObjectForBeanInstance进行加工得到我们想要的实例

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

        // Don't let calling code try to dereference the factory if the bean isn't a factory.
        // 如果name以&开头
        if (BeanFactoryUtils.isFactoryDereference(name)) {
            // NullBean类型直接返回
            if (beanInstance instanceof NullBean) {
                return beanInstance;
            }
            // 以&开头代表想要获取FactoryBean实例,但得到的实例实际上不是FactoryBean实例,抛出异常
            if (!(beanInstance instanceof FactoryBean)) {
                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
            }
            if (mbd != null) {
                mbd.isFactoryBean = true;
            }
            return beanInstance;
        }

        // Now we have the bean instance, which may be a normal bean or a FactoryBean.
        // If it's a FactoryBean, we use it to create a bean instance, unless the
        // caller actually wants a reference to the factory.
        // 普通类型bean实例,直接返回该实例
        if (!(beanInstance instanceof FactoryBean)) {
            return beanInstance;
        }

        // 如果上述均不满足,调用BeanFactory工厂getObject方法创建bean
        Object object = null;
        if (mbd != null) {
            mbd.isFactoryBean = true;
        }
        else {
            // 从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)) {
                // 合并BeanDefinition
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            // synthetic字面意思是合成的,true代表非应用本身创建的bean,如使用<aop:config>创建的自动代理bean
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            // 继续调用getObjectFromFactoryBean方法创建bean
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }

可以分成三个部分查看流程:

  • 首先处理name以&开头的情况,如果是NullBean,直接返回实例beanInstance;如果对应实例beanInstance不是FactoryBean类型,抛出异常;否则,返回实例beanInstance
  • 如果是普通bean,直接返回对应实例
  • 如果是其他情况,通过getObjectFromFactoryBean获得bean实例

5. AbstractBeanFactory#getObjectFromFactoryBean

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        // 单例模式,有使用缓存
        // containsSingleton方法判断了singletonObjects是否包含beanName,而singletonObjects在doGetBean中sharedInstance为空的分支中,通过getSingleton方法进行了put
        // 而这一步是sharedInstance不为空的分支走进来的,所以这时候singletonObjects应该是已经包含beanName了
        if (factory.isSingleton() && containsSingleton(beanName)) {
            // getSingletonMutex返回singletonObjects对象,单例模式在并发情况下需要保证只创建一个实例,所以需要对singletonObjects加锁
            synchronized (getSingletonMutex()) {
                Object object = this.factoryBeanObjectCache.get(beanName);
                if (object == null) {
                    // doGetObjectFromFactoryBean调用了getObject方法
                    object = doGetObjectFromFactoryBean(factory, beanName);
                    // Only post-process and store if not put there already during getObject() call above
                    // (e.g. because of circular reference processing triggered by custom getBean calls)
                    // TODO
                    // 没看懂这几句代码
                    // 貌似是上述的getObject方法调用期间,只会在不存在实例的情况下才创建实例并保存,所以这里要再次获取一次,保证获取的是第一次创建的实例
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if (alreadyThere != null) {
                        object = alreadyThere;
                    }
                    else {
                        // 进入这个分支意味着object是第一次创建的实例,这时候需要通过shouldPostProcess判断是否进行后置处理
                        // PostProcess中文含义便是"后处理"
                        if (shouldPostProcess) {
                            // TODO
                            // 不是很懂这里判断的含义
                            if (isSingletonCurrentlyInCreation(beanName)) {
                                // Temporarily return non-post-processed object, not storing it yet..
                                return object;
                            }
                            // 将beanName加入singletonsCurrentlyInCreation
                            beforeSingletonCreation(beanName);
                            try {
                                // 应用后置处理方法
                                object = postProcessObjectFromFactoryBean(object, beanName);
                            }
                            catch (Throwable ex) {
                                throw new BeanCreationException(beanName,
                                        "Post-processing of FactoryBean's singleton object failed", ex);
                            }
                            finally {
                                // 将beanName从singletonsCurrentlyInCreation移除
                                afterSingletonCreation(beanName);
                            }
                        }
                        if (containsSingleton(beanName)) {
                            // 已创建的实例写入缓存
                            this.factoryBeanObjectCache.put(beanName, object);
                        }
                    }
                }
                return object;
            }
        }
        else {
            // 原型模式,不使用缓存,每次重新创建
            Object object = doGetObjectFromFactoryBean(factory, beanName);
            if (shouldPostProcess) {
                try {
                    object = postProcessObjectFromFactoryBean(object, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                }
            }
            return object;
        }
    }

该段代码主要是做了一些后置处理,核心在于doGetObjectFromFactoryBean

6. AbstractBeanFactory#doGetObjectFromFactoryBean

    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final 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 {
                // 调用getObject方法创建实例
                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);
        }

        // Do not accept a null value for a FactoryBean that's not fully
        // initialized yet: Many FactoryBeans just return null then.
        if (object == null) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            object = new NullBean();
        }
        return object;
    }

7. AbstractBeanFactory#getMergedLocalBeanDefinition

    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        // Quick check on the concurrent map first, with minimal locking.
        // 查阅缓存
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null && !mbd.stale) {
            return mbd;
        }
        // getBeanDefinition(beanName):从beanDefinitionMap获取BeanDefinition
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }
    protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
            throws BeanDefinitionStoreException {

        return getMergedBeanDefinition(beanName, bd, null);
    }
    //  <bean id="hello" class="xyz.coolblog.innerbean.Hello">
    //    <property name="content" value="hello"/>
    //  </bean>
    //
    //  <bean id="hello-child" parent="hello">
    //    <property name="content" value="I`m hello-child"/>
    //  </bean>
    // spring支持通过以上方式进行配置继承,子类从而可以覆盖或者继承父类的配置
    protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {

        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;
            RootBeanDefinition previous = null;

            // Check with full lock now in order to enforce the same merged instance.
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }


            // stale:陈旧,该属性用于标示是否需要进行重新合并
            if (mbd == null || mbd.stale) {
                previous = mbd;
                if (bd.getParentName() == null) {
                    // 没有父类
                    // Use copy of given root bean definition.
                    if (bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                    }
                    else {
                        mbd = new RootBeanDefinition(bd);
                    }
                }
                else {
                    // 有父类,进行合并
                    // Child bean definition: needs to be merged with parent.
                    BeanDefinition pbd;
                    try {
                        String parentBeanName = transformedBeanName(bd.getParentName());
                        if (!beanName.equals(parentBeanName)) {
                            // 子beanName和父beanName不同的情况下
                            // 递归调用,获取parentBeanDefinition
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            // 子beanName和父beanName相同的情况下
                            // TODO 没看懂
                            // 看起来也是一个递归调用,但是只在parent是ConfigurableBeanFactory的情况下进行递归调用
                            // 递归后最终还是得回到这个方法,并且此时并非是ConfigurableBeanFactory类型(也就是不再进入这个分支)
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }
                            else {
                                throw new NoSuchBeanDefinitionException(parentBeanName,
                                        "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                                        "': cannot be resolved without a ConfigurableBeanFactory parent");
                            }
                        }
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                    }
                    // Deep copy with overridden values.
                    // 覆盖或者继承父类的配置
                    mbd = new RootBeanDefinition(pbd);
                    mbd.overrideFrom(bd);
                }

                // Set default singleton scope, if not configured before.
                // 没配置的情况下设置默认singleton scope
                if (!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope(SCOPE_SINGLETON);
                }

                // A bean contained in a non-singleton bean cannot be a singleton itself.
                // Let's correct this on the fly here, since this might be the result of
                // parent-child merging for the outer bean, in which case the original inner bean
                // definition will not have inherited the merged outer bean's singleton status.
                // 容器是非singleton并且bean是singleton的情况下,bean不可能是singleton,此时需要进行覆盖
                if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    mbd.setScope(containingBd.getScope());
                }

                // Cache the merged bean definition for the time being
                // (it might still get re-merged later on in order to pick up metadata changes)
                // 开启缓存模式的情况下进行缓存
                if (containingBd == null && isCacheBeanMetadata()) {
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }
            if (previous != null) {
                // 重新合并,使用previous的配置覆盖mbd的配置
                copyRelevantMergedBeanDefinitionCaches(previous, mbd);
            }
            return mbd;
        }
    }

主要逻辑就是对BeanDefinition整合一下parentBeanDefinition,对于BeanDefnition,可以戳《Spring源码解析(一)-BeanDefinition加载》

总结

画个流程图理清一下doGetBean的流程

doGetBean方法流程
本文仅讲述了获取单例bean的流程,流程图中createBean等源码的解析放置于下一章节《Spring源码解析(八)-创建单例bean》

相关文章

网友评论

      本文标题:Spring源码解析(七)-获取单例bean

      本文链接:https://www.haomeiwen.com/subject/qwauuhtx.html