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)