BeanDefinition 合併

 

BeanDefinition 的合併

  • 1.BeanDefinition 有父子關係,有個屬性叫parentName,經過parentName能夠設置BeanDefinition的父子關係
  • 2.爲何要設置BeanDefinition的父子關係,由於子類能夠繼承父類的屬性,抽出共性,跟java的繼承有點像
  • 3.BeanDefinition 的合併過程就是將父子關係的 BeanDefinition 屬性合併起來,若是有相同的就使用子類的屬性值 例子:
    AnnotationConfigApplicationContext applicationContext
                   = new AnnotationConfigApplicationContext(springConfiguration.class);
           //父 RootBeanDefinition        
           RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
           rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT);
           rootBeanDefinition.getPropertyValues().add("name","xiaoming");
           applicationContext.registerBeanDefinition("parent",rootBeanDefinition);
       
       //子 ChildBeanDefinition ,會繼承使用父類已有的屬性值,可是若是屬性值衝突,不同
       //那麼合併過程當中就會使用子類的
           ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent");
           childBeanDefinition.setBeanClass(A.class);
           childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
          
    複製代碼

    何時作合併

    在初始化bean工廠的過程當中調用: PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors->DefaultListableBeanFactory.getBeanNamesForType
  • DefaultListableBeanFactory.getBeanNamesForType
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
        //....... 
            return doGetBeanNamesForType
            //......
    }
複製代碼
  • DefaultListableBeanFactory#doGetBeanNamesForType
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        List<String> result = new ArrayList<>();

        // 遍歷全部的 beanDefinitionNames
        for (String beanName : this.beanDefinitionNames) {
            // Only consider bean as eligible if the bean name
            // is not defined as alias for some other bean.
            if (!isAlias(beanName)) {
                try {
                //獲取合併的bd
                    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //.....
    }
複製代碼
  • AbstractBeanFactory#getMergedLocalBeanDefinition
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        // 先嚐試從緩存獲取bd(就是一個map)
        RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null) {
            return mbd;
        }
        //合併bd
        return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
    }
複製代碼
  • AbstractBeanFactory#getMergedBeanDefinitionjava

    protected RootBeanDefinition getMergedBeanDefinition(
            String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
            throws BeanDefinitionStoreException {
    
        synchronized (this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;
    
            // 先從緩存拿合併的bd
            if (containingBd == null) {
                mbd = this.mergedBeanDefinitions.get(beanName);
            }
              //合併的bd爲空就進行bd合併
            if (mbd == null) {
               //若是父類爲空,就不進行bd合併
                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 {
                    // 進行bd合併
                    BeanDefinition pbd;
                    try {
                        String parentBeanName = transformedBeanName(bd.getParentName());
                        if (!beanName.equals(parentBeanName)) {
                           //父類的bd可能也須要合併,因此調用 getMergedBeanDefinition
                            pbd = getMergedBeanDefinition(parentBeanName);
                        }
                        else {
                            BeanFactory parent = getParentBeanFactory();
                            if (parent instanceof ConfigurableBeanFactory) {
                                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
                            }                       
                        }
                    }
                    //進行bd合併,子類覆蓋父類的,若是子類沒有,就用父類的屬性
                    mbd = new RootBeanDefinition(pbd);
                    mbd.overrideFrom(bd);
                }
    
                // Set default singleton scope, if not configured before.
                if (!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
                }
            }
    
            return mbd;
        }
    }
    
    複製代碼
相關文章
相關標籤/搜索