BeanDefinition 合并
【摘要】
BeanDefinition 的合并
1.BeanDefinition 有父子关系,有个属性叫parentName,通过parentName可以设置BeanDefinition的父子关系2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像3.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#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;
-
}
-
}
-
-
复制代码
-
文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。
原文链接:javaedge.blog.csdn.net/article/details/108177864
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)