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
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; } } 复制代码