BeanDefinition 的合并
-
1.BeanDefinition 有父子关系,有个属性叫
parentName,通过parentName可以设置BeanDefinition的父子关系 -
2.为什么要设置BeanDefinition的父子关系,因为子类可以继承父类的属性,抽出共性,跟java的继承有点像
-
3.BeanDefinition 的合并过程就是将父子关系的 BeanDefinition 属性合并起来,如果有相同的就使用子类的属性值 例子:
1 AnnotationConfigApplicationContext applicationContext 2 = new AnnotationConfigApplicationContext(springConfiguration.class); 3 //父 RootBeanDefinition 4 RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); 5 rootBeanDefinition.setScope(AbstractBeanDefinition.SCOPE_DEFAULT); 6 rootBeanDefinition.getPropertyValues().add("name","xiaoming"); 7 applicationContext.registerBeanDefinition("parent",rootBeanDefinition); 8 9 //子 ChildBeanDefinition ,会继承使用父类已有的属性值,但是如果属性值冲突,不一样 10 //那么合并过程中就会使用子类的 11 ChildBeanDefinition childBeanDefinition = new ChildBeanDefinition("parent"); 12 childBeanDefinition.setBeanClass(A.class); 13 childBeanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME); 14 15复制代码什么时候做合并
在初始化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<>();
1 // 遍历所有的 beanDefinitionNames 2 for (String beanName : this.beanDefinitionNames) { 3 // Only consider bean as eligible if the bean name 4 // is not defined as alias for some other bean. 5 if (!isAlias(beanName)) { 6 try { 7 //获取合并的bd 8 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 9 //..... 10}复制代码
-
AbstractBeanFactory#getMergedLocalBeanDefinition
1protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { 2 // 先尝试从缓存获取bd(就是一个map) 3 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 4 if (mbd != null) { 5 return mbd; 6 } 7 //合并bd 8 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 9}复制代码
-
AbstractBeanFactory#getMergedBeanDefinition
1protected RootBeanDefinition getMergedBeanDefinition( 2 String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 3 throws BeanDefinitionStoreException { 4 5 synchronized (this.mergedBeanDefinitions) { 6 RootBeanDefinition mbd = null; 7 8 // 先从缓存拿合并的bd 9 if (containingBd == null) { 10 mbd = this.mergedBeanDefinitions.get(beanName); 11 } 12 //合并的bd为空就进行bd合并 13 if (mbd == null) { 14 //如果父类为空,就不进行bd合并 15 if (bd.getParentName() == null) { 16 // Use copy of given root bean definition. 17 if (bd instanceof RootBeanDefinition) { 18 mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); 19 } 20 else { 21 mbd = new RootBeanDefinition(bd); 22 } 23 } 24 else { 25 // 进行bd合并 26 BeanDefinition pbd; 27 try { 28 String parentBeanName = transformedBeanName(bd.getParentName()); 29 if (!beanName.equals(parentBeanName)) { 30 //父类的bd可能也需要合并,所以调用 getMergedBeanDefinition 31 pbd = getMergedBeanDefinition(parentBeanName); 32 } 33 else { 34 BeanFactory parent = getParentBeanFactory(); 35 if (parent instanceof ConfigurableBeanFactory) { 36 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); 37 } 38 } 39 } 40 //进行bd合并,子类覆盖父类的,如果子类没有,就用父类的属性 41 mbd = new RootBeanDefinition(pbd); 42 mbd.overrideFrom(bd); 43 } 44 45 // Set default singleton scope, if not configured before. 46 if (!StringUtils.hasLength(mbd.getScope())) { 47 mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON); 48 } 49 } 50 51 return mbd; 52 } 53} 54 55复制代码