spring getMergedLocalBeanDefinition

doGetBean 这个方法中涉及到 getMergedLocalBeanDefinition 这么一个方法,代码如下:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	.....
	
	try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				
				......
					}
					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;
			}		
}

上面只是贴出了其中一段代码。
这个方法如下:

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) {
		return mbd;
	}
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
			throws BeanDefinitionStoreException {

	return getMergedBeanDefinition(beanName, bd, null);
}

protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
			throws BeanDefinitionStoreException {

	synchronized (this.mergedBeanDefinitions) {
		RootBeanDefinition mbd = 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) {
			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 {
				......
			}
			......
		}

		return mbd;
	}
}
	
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
	BeanDefinition bd = this.beanDefinitionMap.get(beanName);
	if (bd == null) {
		if (logger.isTraceEnabled()) {
			logger.trace("No bean named '" + beanName + "' found in " + this);
		}
		throw new NoSuchBeanDefinitionException(beanName);
	}
	return bd;
}
	

上面这段代码大家只是向大家展示了这个方法的大概的调用逻辑,大家先关注 getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 这个方法中 bd.getParentName() == null 这段代码。这段代码就是这个方法存在的原因。
在 xml 的配置中,bean 的定义有这么一个熟悉 parent。如下:

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName">

    <bean id="parentBean" class="com.test.merge.ParentObject">
        <property name="score" value="1200"></property>
    </bean>
    <bean id="child" paren="parentBean" class="com.test.merge.ComplexObject">
        <property name="sex" value="1"></property>
        <property name="name" value="11221"></property>
    </bean>
</beans>

parent 这个属性有两个功能:

  • child 这个 bean 能够获取 parentBean 所定义的属性值。这个前提是 child 这个 bean 必须要拥有这些属性,不管是 child 自己有这个属性,还是从其父类中继承过来的属性。其实说到底还是 child 自己必须要有这个属性,因为从父类继承过来也是在解析过程中将父类的属性设置到子类的 BeanDefinition 中。如果 child 中属性的赋值跟 parentBean 中属性的赋值冲突的情况下,child 中的赋值会覆盖 parentBean 中的赋值。
  • child 不存在 class 这个属性时,可以使用 parentBean 的 class。

parent 这个属性跟 bean 的继承没有关系。这个属性的存在是为了方便多个 bean 存在相同的属性时,可以共用同一个 parent,跟 bean 的继承有相似的作用,但它俩不是一个东西。这点大家要注意下。

getMergedLocalBeanDefinition 其实就是来处理 parent 这个属性的。当然其下层的 getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 的这个方法不仅仅是处理 parent 属性。其实其还需要处理 containingBd 这个属性的,这个我们后续解释。

这个方法的目的就是将 parent 这个属性对应的 bean 定义中的信息设置到 child 中去。

这个方法的代码不是特别复杂,大家在了解了其用途之后可以自行下去看下。

希望对您有帮助

QQ
在这里插入图片描述
QQ群
在这里插入图片描述

微信:TY_3268407924
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值