Spring到处可见的getMergedBeanDefinition,到底什么是MergedBeanDefinition

文章详细解释了SpringAbstractBeanFactory类中的getMergedLocalBeanDefinition方法,涉及BeanDefinition的合并过程,尤其是在处理父子BeanDefinition时的逻辑,包括缓存和跨BeanFactory的查找策略。
摘要由CSDN通过智能技术生成
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    // 返回合并的RootBeanDefinition,如果指定的bean存在父bean定义,则需要合并父bean的定义
    // 为什么存在父BeanDefinition,因为BeanDefinition也存在父子关系,子BeanDefinition需要继承父的BeanDefinition,并且还要保存自身的定义配置
    // 为什么getMergedLocalBeanDefinition,为什么是Merged"Local"BeanDefinition呢?因为之前凡是调用过这个方法处理过的beanName,都会被缓存到本地
    // 并且缓存的是合并过后的RootBeanDefinition,不在存在父BeanDefinition了

    /**
     * <pre>
     *  例如: 我们手动注入两个BD,并且两个BD存在父子关系
     *  context.registerBeanDefinition("luck", new RootBeanDefinition(ParentBean.class));
     *  // 定义一个子BeanDefinition,父beanName为luck
     *  // 从而ChildBeanDefinition的配置会与RootBeanDefinition进行合并,并且保存ChildBeanDefinition的属性
     *  ChildBeanDefinition definition = new ChildBeanDefinition("luck");
     *  definition.setBeanClass(ChildBean.class);
     *  context.registerBeanDefinition("child", definition);
     *
     *    这个方法所做的逻辑就是,获取beanName对应的BD,如果BD不存在父BD,直接封装成将当前Bean的BD拷贝到RootBeanDefinition中,并且缓存到mergedBeanDefinitions中
     *    如果DB存在父BD,那么判断当前父beanName和子beanName在不在同一个BeanFactory中,如果在,直接获取父BD,然后与当前BD进行合并成新的RootBeanDefinition
     *    如果父beanName和子beanName不在同一BeanFactory中,表示父Bean可能在当前BeanFactory的父BeanFactory(父容器)中,于是从父容器获取父BD
     *    如果获取到父BD,那么与当前BD进行合并,返回RootBeanDefinition,如果没找到对应的父BD,抛出异常
     * </pre>
     */
    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        // 查找mergedBeanDefinitions是否处理过这个BeanName
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        // 如果处理过,并且不需要合并BeanDefinition
        if (mbd != null && !mbd.stale) {
            return mbd;
        }
        // 获取当前beanName的BeanDefinition
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)) {
            return getMergedBeanDefinition(beanName, bd, containingBd = null) {
                // 加锁处理
                synchronized (this.mergedBeanDefinitions) {
                    // 最终合并之后的BeanDefinition
                    RootBeanDefinition mbd = null;
                    // 上一个合并的BeanDefinition
                    RootBeanDefinition previous = null;
                    // 再次判断containingBd是否为空,防止并发操作,上面传递的为null
                    if (containingBd == null) {
                        // 获取缓存
                        mbd = this.mergedBeanDefinitions.get(beanName);
                    }
                    // 如果没有保存过mergedBeanDefinitions中,或者就算保存了
                    // stale标识这还需要合并当前BeanDefinition
                    if (mbd == null || mbd.stale) {
                        // 保存合并的BeanDefinition
                        previous = mbd;
                        // 如果当前Bean的BeanDefinition中,不存在父名称
                        // 表示不存在BeanDefinition的父子关系,就不需要对BeanDefinition进行合并
                        if (bd.getParentName() == null) {
                            // 如果是RootBeanDefinition类型
                            if (bd instanceof RootBeanDefinition) {
                                // 拷贝一份BeanDefinition
                                mbd = ((RootBeanDefinition) bd).cloneBeanDefinition() {
                                    return new RootBeanDefinition(this) {
                                        // AbstractBeanDefinition
                                        // 设置一些bean的定义信息
                                        super(original)
                                        setParentName(original.getParentName());
                                        setBeanClassName(original.getBeanClassName());
                                        setScope(original.getScope());
                                        setAbstract(original.isAbstract());
                                        setFactoryBeanName(original.getFactoryBeanName());
                                        setFactoryMethodName(original.getFactoryMethodName());
                                        setRole(original.getRole());
                                        setSource(original.getSource());
                                        copyAttributesFrom(original);
                                        if(original instanceof AbstractBeanDefinition){
                                            AbstractBeanDefinition originalAbd = (AbstractBeanDefinition) original;
                                            if (originalAbd.hasBeanClass()) {
                                                setBeanClass(originalAbd.getBeanClass());
                                            }
                                            if (originalAbd.hasConstructorArgumentValues()) {
                                                setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
                                            }
                                            if (originalAbd.hasPropertyValues()) {
                                                setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
                                            }
                                            if (originalAbd.hasMethodOverrides()) {
                                                setMethodOverrides(new MethodOverrides(originalAbd.getMethodOverrides()));
                                            }
                                            Boolean lazyInit = originalAbd.getLazyInit();
                                            if (lazyInit != null) {
                                                setLazyInit(lazyInit);
                                            }
                                            setAutowireMode(originalAbd.getAutowireMode());
                                            setDependencyCheck(originalAbd.getDependencyCheck());
                                            setDependsOn(originalAbd.getDependsOn());
                                            setAutowireCandidate(originalAbd.isAutowireCandidate());
                                            setPrimary(originalAbd.isPrimary());
                                            copyQualifiersFrom(originalAbd);
                                            setInstanceSupplier(originalAbd.getInstanceSupplier());
                                            setNonPublicAccessAllowed(originalAbd.isNonPublicAccessAllowed());
                                            setLenientConstructorResolution(originalAbd.isLenientConstructorResolution());
                                            setInitMethodName(originalAbd.getInitMethodName());
                                            setEnforceInitMethod(originalAbd.isEnforceInitMethod());
                                            setDestroyMethodName(originalAbd.getDestroyMethodName());
                                            setEnforceDestroyMethod(originalAbd.isEnforceDestroyMethod());
                                            setSynthetic(originalAbd.isSynthetic());
                                            setResource(originalAbd.getResource());
                                        }else{
                                            setConstructorArgumentValues(new ConstructorArgumentValues(original.getConstructorArgumentValues()));
                                            setPropertyValues(new MutablePropertyValues(original.getPropertyValues()));
                                            setLazyInit(original.isLazyInit());
                                            setResourceDescription(original.getResourceDescription());
                                        }
                                    }
                                    this.decoratedDefinition = original.decoratedDefinition;
                                    this.qualifiedElement = original.qualifiedElement;
                                    this.allowCaching = original.allowCaching;
                                    this.isFactoryMethodUnique = original.isFactoryMethodUnique;
                                    this.targetType = original.targetType;
                                    this.factoryMethodToIntrospect = original.factoryMethodToIntrospect;
                                }
                            }
                        } else {
                            // 其他类型也一样,重新新建一个新的BeanDefinition
                            mbd = new RootBeanDefinition(bd);
                        }
                    }
                    // 如果存在父名称,表示当前bean需要与父BeanDefinition进行合并
                    else {
                        // 父的BeanDefinition
                        BeanDefinition pbd;
                        try {
                            // 获取当前设置的父名称在父容器的的BeanName
                            String parentBeanName = transformedBeanName(bd.getParentName());
                            // 如果父名称和和本身的beanName不一样
                            if (!beanName.equals(parentBeanName)) {
                                // 通过父beanName继续获取BeanName,相当于再走一遍逻辑,通过父Name去找MergedBeanDefinition的逻辑
                                pbd = getMergedBeanDefinition(parentBeanName) {
                                    // 解析beanName,这里是父BeanName
                                    String beanName = transformedBeanName(name);
                                    // 如果当前的bean工厂不存在这个bean,那么这个bean有可能在父工厂中
                                    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
                                        // 递归不断获取父工厂以及父工厂的父工厂中的BeanDefinition
                                        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
                                    }
                                    // 如果当前Bean工厂存在这个Bean,表示父子BeanDefinition在同一个Bean工厂中
                                    // 继续获取父BeanName的BeanDefinition
                                    // 又到了最开始的逻辑,这里又是一个递归
                                    // 这个方法所做的逻辑就是,获取beanName对应的BD,如果BD不存在父BD,直接封装成将当前Bean的BD拷贝到RootBeanDefinition中,并且缓存到mergedBeanDefinitions中
                                    // 如果DB存在父BD,那么判断当前父beanName和子beanName在不在同一个BeanFactory中,如果在,直接获取父BD,然后与当前BD进行合并成新的RootBeanDefinition
                                    // 如果父beanName和子beanName不在同一BeanFactory中,表示父Bean可能在当前BeanFactory的父BeanFactory(父容器)中,于是从父容器获取父BD
                                    // 如果获取到父BD,那么与当前BD进行合并,返回RootBeanDefinition,如果没找到对应的父BD,抛出异常
                                    return getMergedLocalBeanDefinition(beanName);
                                }
                            }
                            // 如果两个名称一样
                            else {
                                // 获取父工厂
                                BeanFactory parent = getParentBeanFactory();
                                // 获取父工厂的存在此beanName对应的BeanDefinition
                                if (parent instanceof ConfigurableBeanFactory) {
                                    pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                                }
                                // 如果父工厂不是ConfigurableBeanFactory类型,直接报错
                                else {
                                    throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent");
                                }
                            }
                        } catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
                        }
                        // 克隆父BD,使用父BD作为基础配置
                        mbd = new RootBeanDefinition(pbd);
                        // 保存子BD原来的配置,覆盖父BD
                        mbd.overrideFrom(bd);
                    }

                    // 设置默认的单例作用域,如果之前没有配置的话
                    if (!StringUtils.hasLength(mbd.getScope())) {
                        mbd.setScope(SCOPE_SINGLETON);
                    }

                    // 如果作用域不是默认的,要保存之前设置的作用域
                    if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                        mbd.setScope(containingBd.getScope());
                    }
                    // 第一次处理,containingBd肯定是为null,因为传递的就是null
                    // isCacheBeanMetadata:默认值为为true,需要缓存Bean定义
                    // 保存合并后的BeanDefinition
                    // 所以,只要调用这个方法,都会存在合并后的BD,保存到mergedBeanDefinitions中
                    if (containingBd == null && isCacheBeanMetadata()) {
                        this.mergedBeanDefinitions.put(beanName, mbd);
                    }
                }
                // 如果以前的BeanDefinition previous不为null,
                if (previous != null) {
                    // 将以前的某些配置拷贝到合并后的BeanDefinition
                    copyRelevantMergedBeanDefinitionCaches(previous, mbd) {
                        if (ObjectUtils.nullSafeEquals(mbd.getBeanClassName(), previous.getBeanClassName()) &&
                                ObjectUtils.nullSafeEquals(mbd.getFactoryBeanName(), previous.getFactoryBeanName()) &&
                                ObjectUtils.nullSafeEquals(mbd.getFactoryMethodName(), previous.getFactoryMethodName())) {
                            ResolvableType targetType = mbd.targetType;
                            ResolvableType previousTargetType = previous.targetType;
                            if (targetType == null || targetType.equals(previousTargetType)) {
                                mbd.targetType = previousTargetType;
                                mbd.isFactoryBean = previous.isFactoryBean;
                                mbd.resolvedTargetType = previous.resolvedTargetType;
                                mbd.factoryMethodReturnType = previous.factoryMethodReturnType;
                                mbd.factoryMethodToIntrospect = previous.factoryMethodToIntrospect;
                            }
                        }
                    }
                }
                return mbd;
            }
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值