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#getMergedBeanDefinitionjava
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; } } 複製代碼