protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)throws BeanDefinitionStoreException {synchronized(this.mergedBeanDefinitions){/*** 准备一个RootBeanDefinition变量引用,用于记录要构建和最终要返回的BeanDefinition */ 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);}if(mbd ==null|| mbd.stale){ previous = mbd;/*** 判读有没有指定parent */if(bd.getParentName()==null){/**
* Use copy of given root bean definition.
* 如果自己就是一个RootBeanDefinition,那么就克隆一下,生成一个新的RootBeanDefinition
*/if(bd instanceof RootBeanDefinition){ mbd =((RootBeanDefinition) bd).cloneBeanDefinition();}else{ mbd =new RootBeanDefinition(bd);}}else{/**
* Child bean definition: needs to be merged with parent.
* 定义父亲的BeanDefinition
*/ BeanDefinition pbd;try{/*** 拿到这个bean的parent的名字 */ String parentBeanName = transformedBeanName(bd.getParentName());/*** 当前名字不等于parentBean的名字,递归处理,一直往上找 */if(!beanName.equals(parentBeanName)){ pbd = getMergedBeanDefinition(parentBeanName);}else{ BeanFactory parent = getParentBeanFactory();if(parent instanceof ConfigurableBeanFactory){ pbd =((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);}else{thrownew NoSuchBeanDefinitionException(parentBeanName,"Parent name '"+ parentBeanName +"' is equal to bean name '"+ beanName +"': cannot be resolved without a ConfigurableBeanFactory parent");}}}catch(NoSuchBeanDefinitionException ex){thrownew BeanDefinitionStoreException(bd.getResourceDescription(), beanName,"Could not resolve parent bean definition '"+ bd.getParentName()+"'", ex);}// Deep copy with overridden values.
/*** 生成一个新的BeanDefinition,并且覆盖掉父亲的属性 */ mbd =new RootBeanDefinition(pbd); mbd.overrideFrom(bd);}// Set default singleton scope, if not configured before.
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.
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()){/*** 放到map中 */this.mergedBeanDefinitions.put(beanName, mbd);}}if(previous !=null){ copyRelevantMergedBeanDefinitionCaches(previous, mbd);}return mbd;}}
没有父BeanDefinition的情况
源码如下:
1
2
3
4
5
6
7
8
9
10
11
if(bd.getParentName()==null){/**
* Use copy of given root bean definition.
* 如果自己就是一个RootBeanDefinition,那么就克隆一下,生成一个新的RootBeanDefinition
*/if(bd instanceof RootBeanDefinition){ mbd =((RootBeanDefinition) bd).cloneBeanDefinition();}else{ mbd =new RootBeanDefinition(bd);}}
这时候肯定会有疑问,两个合并的代码不是一模一样吗?
其实不是,如果一个 BeanDefinition 是 RootBeanDefinition 的子类,那么调用克隆方法的时候,就会 new 一个该子类,然后开始克隆,比如 new ConfigurationClassBeanDefinition(this)。