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 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#getMergedBeanDefinition

    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;
        }
    }
    
    复制代码

 

你可能感兴趣的:(BeanDefinition 合并)