天天看點

Spring Framework 源碼閱讀(二):BeanDefinition的作用

Spring Framework 源碼閱讀(二):BeanDefinition的作用

上一篇​

​Spring Framework​

​​源碼閱讀部落格,部落客介紹了​

​Aware​

​​接口及其實作類的作用,​

​Aware​

​​的設計模式是模闆模式,而​

​BeanDefinition​

​的設計模式也是模闆模式,它們都基于某種職責定義了一個模闆,符合開閉原則,對擴充開放,對修改關閉,擴充在子類中實作。

  • ​​Spring Framework 源碼閱讀(一):Aware接口及其實作類的作用​​
  • ​​設計模式-模闆模式(Template Pattern)​​
  • ​​設計模式的七大原則​​

​BeanDefinition​

​接口的定義

package org.springframework.beans.factory.config;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
 * A BeanDefinition describes a bean instance, which has property values,
 * constructor argument values, and further information supplied by
 * concrete implementations.
 *  * <p>This is just a minimal interface: The main intention is to allow a
 * {@link BeanFactoryPostProcessor} to introspect and modify property values
 * and other bean metadata.
 *  * @author Juergen Hoeller
 * @author Rob Harrop
 * @since 19.03.2004
 * @see ConfigurableListableBeanFactory#getBeanDefinition
 * @see org.springframework.beans.factory.support.RootBeanDefinition
 * @see org.springframework.beans.factory.support.ChildBeanDefinition
 */
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    ...
}      
  • ​BeanDefinition​

    ​​描述​

    ​bean​

    ​​執行個體,比如​

    ​bean​

    ​執行個體具有的屬性值、構造函數參數值以及由具體實作提供的進一步資訊。
  • 主要目的是允許​

    ​BeanFactoryPostProcessor​

    ​​檢查和修改屬性值以及其他​

    ​bean​

    ​​中繼資料,​

    ​BeanFactoryPostProcessor​

    ​部落客以後會進行介紹,不然會涉及到很多其他知識,顯得雜亂無章,要盡量遵守單一職責原則。

為什麼需要​

​BeanDefinition​

​​?這就要讨論​

​Java​

​​對象和​

​bean​

​​有什麼不同,很顯然​

​bean​

​​也是​

​Java​

​​對象,但它擁有​

​Java​

​​對象所沒有的功能,它可以在​

​Spring​

​​容器中很容易實作自動注入、懶加載、多種作用域和根據各種限定條件進行初始化等,​

​Java​

​​中的類可以描述該類執行個體的屬性和行為,是以​

​bean​

​​也需要有描述它附加功能的定義,不然它隻是一個​

​Java​

​​對象而已,這就是​

​BeanDefinition​

​的作用,從接口的命名也可看出來。

​BeanDefinition​

​接口的方法和屬性:

Spring Framework 源碼閱讀(二):BeanDefinition的作用

屬性

  • ​SCOPE_SINGLETON​

    ​​:​

    ​bean​

    ​​的單例作用域,把​

    ​bean​

    ​​設定為單例作用域時,​

    ​Spring​

    ​​容器隻會建立該​

    ​bean​

    ​​的唯一執行個體。這個單一執行個體會被存儲到單例緩存(​

    ​singleton cache​

    ​​)中,并且所有針對該​

    ​bean​

    ​的後續請求和引用都将傳回被緩存的對象執行個體。
  • ​SCOPE_PROTOTYPE​

    ​​:​

    ​bean​

    ​​的原型作用域,把​

    ​bean​

    ​​設定為原型作用域時,每次對​

    ​bean​

    ​​的請求(将其注入到另一個​

    ​bean​

    ​​中,或者以程式的方式調用容器的​

    ​getBean()​

    ​​方法)時​

    ​Spring​

    ​​容器都會建立一個新的​

    ​bean​

    ​​執行個體。​

    ​bean​

    ​​的其他作用域(​

    ​request​

    ​​、​

    ​session​

    ​​、​

    ​globalSession​

    ​​)需要在​

    ​Web​

    ​環境中才能使用,以後部落客再進行詳細介紹。
  • ​ROLE_APPLICATION​

    ​​:​

    ​bean​

    ​​的角色訓示,訓示該​

    ​BeanDefinition​

    ​​是應用程式的主要部分。通常對應于使用者定義的​

    ​bean​

    ​。
  • ​ROLE_SUPPORT​

    ​​:​

    ​bean​

    ​​的角色訓示,訓示該​

    ​BeanDefinition​

    ​​是某些配置(通常是外部的​

    ​ComponentDefinition​

    ​)的支撐部分。
  • ​ROLE_INFRASTRUCTURE​

    ​​:​

    ​bean​

    ​​的角色訓示,訓示該​

    ​BeanDefinition​

    ​完全提供背景角色,與終端使用者無關。

方法

  • ​setParentName​

    ​​、​

    ​getParentName​

    ​​:設定和擷取父​

    ​BeanDefinition​

    ​​名稱的方法,為了描述​

    ​bean​

    ​​之間的繼承關系,​

    ​BeanDefinition​

    ​​也有父子關系,之後會介紹到合并​

    ​BeanDefinition​

    ​的概念。
  • ​setBeanClassName​

    ​​、​

    ​getBeanClassName​

    ​​:設定和擷取​

    ​bean​

    ​的類名。
  • ​setScope​

    ​​、​

    ​getScope​

    ​​:設定和擷取​

    ​bean​

    ​的作用域。
  • ​setLazyInit​

    ​​、​

    ​isLazyInit​

    ​​:設定​

    ​bean​

    ​​為懶加載、判斷​

    ​bean​

    ​是否為懶加載。
  • ​setDependsOn​

    ​​、​

    ​getDependsOn​

    ​​:設定和擷取​

    ​bean​

    ​​所依賴的​

    ​bean​

    ​​的名稱數組(保證首先初始化這些​

    ​bean​

    ​)。
  • ​setAutowireCandidate​

    ​​、​

    ​isAutowireCandidate​

    ​​:​

    ​AutowireCandidate​

    ​​表示​

    ​bean​

    ​​是否是自動注入到其他​

    ​bean​

    ​​的候選。僅影響基于類型(​

    ​byType​

    ​​)的自動注入。它不會影響按名稱(​

    ​byName​

    ​​)的顯式引用,即使指定的​

    ​bean​

    ​​未标記為​

    ​autowire​

    ​​候選,也會解析為顯式引用。是以,如果名稱比對,會按名稱自動注入​

    ​bean​

    ​。
  • ​setPrimary​

    ​​、​

    ​isPrimary​

    ​​:設定和判斷​

    ​bean​

    ​​是否是自動注入到其他​

    ​bean​

    ​的首選。
  • ​setFactoryBeanName​

    ​​、​

    ​getFactoryBeanName​

    ​​:​

    ​FactoryBean​

    ​​和​

    ​BeanFactory​

    ​​是不一樣的概念,​

    ​FactoryBean​

    ​​也是​

    ​bean​

    ​​,不過它可以用于建立某一類型的​

    ​bean​

    ​​(所有是一個​

    ​factory​

    ​​,也是一個​

    ​bean​

    ​​),是以借助​

    ​FactoryBean​

    ​​可以定制化建立​

    ​bean​

    ​​的過程。這兩個方法就是設定和擷取​

    ​bean​

    ​​的​

    ​FactoryBeanName​

    ​​(可以為​

    ​null​

    ​)。
  • ​setFactoryMethodName​

    ​​、​

    ​getFactoryMethodName​

    ​​:​

    ​FactoryBean​

    ​​通過​

    ​FactoryMethod​

    ​​來建立某一類型的​

    ​bean​

    ​​。這兩個方法就是設定和擷取​

    ​bean​

    ​​的​

    ​FactoryMethod​

    ​​(可以為​

    ​null​

    ​)。
  • ​getConstructorArgumentValues​

    ​​、​

    ​hasConstructorArgumentValues​

    ​​:擷取​

    ​bean​

    ​​的構造器參數值、判斷​

    ​bean​

    ​是否有構造器參數值。
  • ​getPropertyValues​

    ​​、​

    ​hasPropertyValues​

    ​​:擷取要應用于​

    ​bean​

    ​​的新執行個體的屬性值、判斷是否有要應用于​

    ​bean​

    ​的新執行個體的屬性值。
  • ​setInitMethodName​

    ​​、​

    ​getInitMethodName​

    ​​:設定和擷取​

    ​bean​

    ​初始化方法的名稱。
  • ​setDestroyMethodName​

    ​​、​

    ​getDestroyMethodName​

    ​​:設定和擷取​

    ​bean​

    ​銷毀方法的名稱。
  • ​setRole​

    ​​、​

    ​getRole​

    ​​:設定和擷取​

    ​bean​

    ​的角色。
  • ​setDescription​

    ​​、​

    ​getDescription​

    ​​:設定和擷取​

    ​BeanDefinition​

    ​​的​

    ​human-readable description​

    ​(便于人類閱讀的描述)。
  • ​getResolvableType​

    ​​:基于​

    ​BeanDefinition​

    ​​或其他特定中繼資料,傳回該​

    ​BeanDefinition​

    ​​的可解析類型。這通常在運作時合并的​

    ​BeanDefinition​

    ​(下面會進行介紹)上完全解析,但不一定在配置時定義的執行個體上完全解析。
  • ​isSingleton​

    ​​、​

    ​isPrototype​

    ​​:判斷​

    ​bean​

    ​​是否是單例、原型​

    ​bean​

    ​。
  • ​isAbstract​

    ​​:判斷​

    ​bean​

    ​​是否是​

    ​abstract​

    ​​,如果是​

    ​abstract​

    ​就不需要執行個體化了。
  • ​getResourceDescription​

    ​​:擷取​

    ​BeanDefinition​

    ​​來自的​

    ​Resource​

    ​的描述(用于在出現錯誤時顯示上下文)。
  • ​getOriginatingBeanDefinition​

    ​​:傳回原始的​

    ​BeanDefinition​

    ​​,如果沒有,則傳回​

    ​null​

    ​。

​BeanDefinition​

​​接口還繼承了​

​AttributeAccessor​

​​接口和​

​BeanMetadataElement​

​接口。

Spring Framework 源碼閱讀(二):BeanDefinition的作用
  • ​AttributeAccessor​

    ​接口:定義了通用的接口,用于向任意對象附加中繼資料或從任意對象通路中繼資料。
  • ​BeanMetadataElement​

    ​​接口:由攜帶配置源對象的​

    ​bean​

    ​中繼資料元素實作的接口。

使用這些定義來描述​

​bean​

​​執行個體,而具體實作下放到子類中,比如​

​AbstractBeanDefinition​

​​、​

​ChildBeanDefinition​

​​、​

​RootBeanDefinition​

​​以及​

​GenericBeanDefinition​

​,接下來部落客會詳細介紹它們的作用。

AbstractBeanDefinition

之前介紹過​

​BeanDefinition​

​​的設計模式是模闆模式,​

​AbstractBeanDefinition​

​​抽象類實作了​

​BeanDefinition​

​接口中的通用方法。

@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
    implements BeanDefinition, Cloneable {
    ...
}      

​AbstractBeanDefinition​

​​是具體、完備的​

​BeanDefinition​

​​基類,并且分解出了​

​GenericBeanDefinition​

​​、​

​RootBeanDefinition​

​​和​

​ChildBeanDefinition​

​的公共屬性。

Spring Framework 源碼閱讀(二):BeanDefinition的作用

通用方法的實作:

/**
   * 指定bean定義的bean類名
   */
  @Override
  public void setBeanClassName(@Nullable String beanClassName) {
    this.beanClass = beanClassName;
  }

  /**
   * 傳回bean定義的bean類名
   */
  @Override
  @Nullable
  public String getBeanClassName() {
    Object beanClassObject = this.beanClass;
    if (beanClassObject instanceof Class) {
      return ((Class<?>) beanClassObject).getName();
    }
    else {
      return (String) beanClassObject;
    }
  }
  
  /**
   * 設定bean的作用域
   */
  @Override
  public void setScope(@Nullable String scope) {
    this.scope = scope;
  }

  /**
   * 傳回bean的作用域名稱
   */
  @Override
  @Nullable
  public String getScope() {
    return this.scope;
  }

  /**
   * 是否是單例bean
   */
  @Override
  public boolean isSingleton() {
    return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
  }

  /**
   *是否是原型bean
   */
  @Override
  public boolean isPrototype() {
    return SCOPE_PROTOTYPE.equals(this.scope);
  }

  /**
   * 是否是abstract,如果是就不會進行執行個體化
   */
  @Override
  public boolean isAbstract() {
    return this.abstractFlag;
  }

  /**
   * 設定bean的加載方式為懶加載
   */
  @Override
  public void setLazyInit(boolean lazyInit) {
    this.lazyInit = lazyInit;
  }

  /**
   * 判斷bean是否設定懶加載
   */
  @Override
  public boolean isLazyInit() {
    return (this.lazyInit != null && this.lazyInit.booleanValue());
  }
  ...      

也添加了新的屬性和方法,涉及到​

​autowire​

​​(裝配​

​bean​

​的屬性):

/**
   * 表示沒有自動裝配的常量
   */
  public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;

  /**
   * 表示按名稱自動裝配bean屬性的常量
   */
  public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;

  /**
   * 表示按類型自動裝配bean屬性的常量
   */
  public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;

  /**
   * 表示通過構造函數自動裝配bean屬性的常量
   */
  public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;

  /**
   * 表示通過bean類的内部檢測來确定适當的自動裝配政策的常量
   */
  @Deprecated
  public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

  /**
   * 設定自動裝配模式
   */
  public void setAutowireMode(int autowireMode) {
    this.autowireMode = autowireMode;
  }

  /**
   * 傳回自動裝配模式
   */
  public int getAutowireMode() {
    return this.autowireMode;
  }

  /**
   * 傳回已解析的自動裝配模式編碼
   */
  public int getResolvedAutowireMode() {
    if (this.autowireMode == AUTOWIRE_AUTODETECT) {
      // 确定是應用setter自動裝配還是構造函數自動裝配
      // 如果它有一個無參數構造函數,則被視為setter自動裝配
      // 否則将嘗試構造函數自動裝配
      Constructor<?>[] constructors = getBeanClass().getConstructors();
      for (Constructor<?> constructor : constructors) {
        if (constructor.getParameterCount() == 0) {
          return AUTOWIRE_BY_TYPE;
        }
      }
      return AUTOWIRE_CONSTRUCTOR;
    }
    else {
      return this.autowireMode;
    }
  }
  ...      

涉及到​

​dependency check​

​(依賴項檢查):

/**
     * 表示沒有依賴項檢查的常量
     */
    public static final int DEPENDENCY_CHECK_NONE = 0;

    /**
     * 表示對象引用的依賴項檢查的常量
     */
    public static final int DEPENDENCY_CHECK_OBJECTS = 1;

    /**
     * 表示“簡單”屬性的依賴項檢查的常量
     */
    public static final int DEPENDENCY_CHECK_SIMPLE = 2;

    /**
     * 表示所有屬性的依賴項檢查的常量
     */
    public static final int DEPENDENCY_CHECK_ALL = 3;
    
    ...
    
    /**
     * 設定依賴項檢查的編碼,就是上面的0、1、2以及3
     */
    public void setDependencyCheck(int dependencyCheck) {
        this.dependencyCheck = dependencyCheck;
    }

    /**
     * 傳回目前依賴項檢查的編碼
     */
    public int getDependencyCheck() {
        return this.dependencyCheck;
    }      

涉及到​

​qualifier​

​(限定符):

/**
   * 注冊一個用于autowire候選解析的限定符。
   */
  public void addQualifier(AutowireCandidateQualifier qualifier) {
    this.qualifiers.put(qualifier.getTypeName(), qualifier);
  }

  /**
   * 傳回bean是否具有指定的限定符
   */
  public boolean hasQualifier(String typeName) {
    return this.qualifiers.containsKey(typeName);
  }

  /**
   * 傳回映射到提供的類型名稱的限定符
   */
  @Nullable
  public AutowireCandidateQualifier getQualifier(String typeName) {
    return this.qualifiers.get(typeName);
  }

  /**
   * 傳回所有的限定符。
   */
  public Set<AutowireCandidateQualifier> getQualifiers() {
    return new LinkedHashSet<>(this.qualifiers.values());
  }

  /**
   * 将限定符從提供的AbstractBeanDefinition複制到此AbstractBeanDefinition
   */
  public void copyQualifiersFrom(AbstractBeanDefinition source) {
    Assert.notNull(source, "Source must not be null");
    this.qualifiers.putAll(source.qualifiers);
  }      

這些都是​

​AbstractBeanDefinition​

​​中新增加的内容(基于特定業務的抽象),當然這些還不是​

​AbstractBeanDefinition​

​​的全貌,大家可以自己去探索一下。接下來會介紹​

​AbstractBeanDefinition​

​​三個比較重要的子類​

​ChildBeanDefinition​

​​、​

​RootBeanDefinition​

​​以及​

​GenericBeanDefinition​

​。

ChildBeanDefinition

子​

​Bean​

​​(繼承了父​

​Bean​

​​)的​

​BeanDefinition​

​​。子​

​BeanDefinition​

​​對父​

​BeanDefinition​

​有固定的依賴關系。

子​

​BeanDefinition​

​​将從父​

​BeanDefinition​

​​繼承構造函數參數值、屬性值和方法重寫,并具有添加新值的選項。如果指定了​

​init method​

​​、​

​destroy method​

​​或​

​static factory method​

​​,它們将覆寫相應父​

​BeanDefinition​

​​的設定。其餘設定将始終取自子​

​BeanDefinition​

​​:​

​depends on​

​​、​

​autowire mode​

​​、​

​dependency check​

​​、​

​singleton​

​​以及​

​lazy init​

​。

自​

​Spring2.5​

​​以來,以程式設計方式注冊​

​BeanDefinition​

​​的首選方法是​

​GenericBeanDefinition​

​​類,它允許通過​

​setParentName​

​​方法動态定義父依賴項。對于大多數用例,這有效地取代了​

​ChildBeanDefinition​

​​類。是以這裡不會詳細地介紹​

​ChildBeanDefinition​

​,它的源碼也比較短,大家可以自己去看看。

RootBeanDefinition

​RootBeanDefinition​

​​表示在運作時支援​

​Spring BeanFactory​

​​中特定​

​bean​

​​的合并​

​BeanDefinition​

​​。它可能是從互相繼承的多個原始​

​BeanDefinition​

​​建立的(通常注冊為​

​GenericBeanDefinition​

​​)。​

​RootBeanDefinition​

​​本質上是運作時的統一​

​BeanDefinition​

​視圖。

​RootBeanDefinition​

​​也可用于在配置階段注冊單個​

​BeanDefinition​

​​。然而,自​

​Spring2.5​

​​以來,以程式設計方式注冊​

​BeanDefinition​

​​的首選方法是​

​GenericBeanDefinition​

​​類。​

​GenericBeanDefinition​

​​的優點是它允許動态定義父依賴項,而不是将角色寫死(​

​hard-coding​

​​)為​

​RootBeanDefinition​

​。

GenericBeanDefinition

​GenericBeanDefinition​

​​是标準​

​BeanDefinition​

​​的一站式服務。與任何​

​BeanDefinition​

​​一樣,它允許指定類以及可選的構造函數參數值和屬性值。可以靈活地配置​

​parentName​

​​屬性,以便從父​

​BeanDefinition​

​​中進行派生。通常,使用​

​GenericBeanDefinition​

​​類注冊使用者可見的​

​BeanDefinition​

​​。在父子關系恰好是預先确定的情況下,使用​

​RootBeanDefinition​

​​和​

​ChildBeanDefinition​

​。

代碼也很短:

Spring Framework 源碼閱讀(二):BeanDefinition的作用

建立module

先在​

​Spring Framework​

​​源碼中增加一個​

​application module​

​,這在之前的博文中已經介紹過了,這裡就不再贅述:

  • ​​編譯 Spring Framework 5.2.17源碼 & 在源碼中使用 ApplicationContext 擷取定義的Bean​​
Spring Framework 源碼閱讀(二):BeanDefinition的作用

​IMessageService​

​接口:

package com.kaven.service;

/**
 * @Author: ITKaven
 * @Date: 2021/09/25 14:04
 * @Leetcode: https://leetcode-cn.com/u/kavenit
 * @Notes:
 */

public interface IMessageService {
  String getMessage();
}      

​MessageServiceImpl​

​實作類:

package com.kaven.service.impl;

import com.kaven.service.IMessageService;
import org.springframework.stereotype.Service;

/**
 * @Author: ITKaven
 * @Date: 2021/09/25 14:05
 * @Leetcode: https://leetcode-cn.com/u/kavenit
 * @Notes:
 */

@Service("message")
public class MessageServiceImpl implements IMessageService {
  @Override
  public String getMessage() {
    return "Hello Kaven";
  }
}      

​Application​

​啟動類:

package com.kaven;

import com.kaven.service.IMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Author: ITKaven
 * @Date: 2021/09/25 13:54
 * @Leetcode: https://leetcode-cn.com/u/kavenit
 * @Notes:
 */

@ComponentScan({"com.kaven"})
public class Application {

  public static void main(String[] args) {
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);

    IMessageService messageServiceBean = (IMessageService) applicationContext.getBean("message");
    System.out.println(messageServiceBean.getMessage());

    Test test = (Test)  applicationContext.getBean("test");
    System.out.println("message bean: " + (test.messageService == messageServiceBean));

    Test test2 = (Test)  applicationContext.getBean("test");
    System.out.println("message bean: " + (test2.messageService == messageServiceBean));
    System.out.println("test bean: " + (test == test2));

    System.out.println(applicationContext.getBeanDefinitionCount());
    Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println);
  }

  @Component("test")
  @Scope("prototype")
  static class Test {
    @Autowired
    private IMessageService messageService;
  }
}      

運作輸出:

> Task :application:Application.main()
Hello Kaven
message bean: true
message bean: true
test bean: false
7
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
application
test
message

BUILD SUCCESSFUL in 19s
61 actionable tasks: 2 executed, 59 up-to-date      

源碼分析 - 注冊​

​BeanDefinition​

上下文中有​

​7​

​​個​

​BeanDefinition​

​​,而​

​test bean​

​​被擷取了兩次,為什麼沒有兩個​

​test BeanDefinition​

​​?因為每個​

​BeanDefinition​

​​描述了一類​

​bean​

​​,并且​

​BeanDefinition​

​​是根據​

​beanName​

​​擷取的,​

​BeanDefinition​

​​類似于類(對象定義),而​

​bean​

​​類似于對象,是以​

​beanName​

​​就類似于​

​className​

​​,類描述了該類所有對象的行為和屬性,​

​BeanDefinition​

​​也是如此。從輸出結果上來看,​

​bean​

​​預設是單例(除非使用​

​@Scope​

​​注解改變其作用域),其實在​

​AbstractBeanDefinition​

​的源碼中也可以發現作用域的預設值。

@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
    implements BeanDefinition, Cloneable {

  /**
   * 預設作用域名稱的常量:"",等同于單例狀态(會被替換為單例,在相關源碼的注釋中有解釋)
   */
  public static final String SCOPE_DEFAULT = "";
  @Nullable
  private String scope = SCOPE_DEFAULT;
  ...
}      

​AbstractBeanDefinition​

​​的源碼中還有一些比較常見配置的預設值,比如​

​bean​

​​預設不是​

​abstract​

​​的(是以需要被執行個體化)、​

​lazyInit​

​​為​

​null​

​​(是以不會被懶加載)、沒有自動裝配、依賴項檢查為​

​DEPENDENCY_CHECK_NONE​

​​(沒有依賴項檢查)、是自動注入的候選​

​bean​

​​和不是首選​

​bean​

​​(​

​primary​

​):

private boolean abstractFlag = false;
  @Nullable
  private Boolean lazyInit;
  private int autowireMode = AUTOWIRE_NO;
  private int dependencyCheck = DEPENDENCY_CHECK_NONE;
  private boolean autowireCandidate = true;
  private boolean primary = false;      

很顯然下面這​

​4​

​​個​

​BeanDefinition​

​​是​

​Spring​

​定義的:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory      

它們在​

​AnnotationConfigUtils​

​​抽象類的​

​registerAnnotationConfigProcessors​

​方法中出現:

public abstract class AnnotationConfigUtils {
    /**
     * 内部管理Configuration注解的處理器的bean名稱
     */
    public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";

    /**
     * 内部管理Autowired注解的處理器的bean名稱
     */
    public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalAutowiredAnnotationProcessor";

    /**
     * 内部管理JSR-250注解的處理器的bean名稱
     */
    public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalCommonAnnotationProcessor";

    /**
     * 内部管理JPA注解的處理器的bean名稱
     */
    public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalPersistenceAnnotationProcessor";

    /**
     * 内部管理EventListener注解的處理器的bean名稱
     */
    public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
            "org.springframework.context.event.internalEventListenerProcessor";

    /**
     * 内部管理EventListenerFactory的bean名稱
     */
    public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
            "org.springframework.context.event.internalEventListenerFactory";
            
    /**
     * 在給定registry中注冊所有相關的注解post processors
     * @param registry 要在其上操作的registry 
     * @param source 觸發此注冊的配置源元素(已提取),可能為null
     * @return Set<BeanDefinitionHolder>,其中包含此調用實際注冊的所有BeanDefinition
     */
    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }
        return beanDefs;
    }
     
    ...
}      

其實這個​

​BeanDefinitionRegistry registry​

​​參數就是部落客在​

​Application​

​​類中建立的​

​AnnotationConfigApplicationContext​

​​執行個體。并且這裡定義的​

​BeanDefinition​

​​是​

​RootBeanDefinition​

​​ 執行個體(​

​RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);​

​,部落客在後面會進行讨論)。

Spring Framework 源碼閱讀(二):BeanDefinition的作用
Spring Framework 源碼閱讀(二):BeanDefinition的作用

​AnnotationConfigApplicationContext​

​​類的父類​

​GenericApplicationContext​

​​實作了​

​BeanDefinitionRegistry​

​ 接口。

Spring Framework 源碼閱讀(二):BeanDefinition的作用

下一步調用了​

​AnnotationConfigUtils​

​​抽象類的的​

​registerPostProcessor​

​​方法(可以看見​

​role​

​​設定為​

​ROLE_INFRASTRUCTURE​

​):

private static BeanDefinitionHolder registerPostProcessor(
      BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(beanName, definition);
    return new BeanDefinitionHolder(definition, beanName);
  }      

之後又調用了​

​GenericApplicationContext​

​​類的​

​registerBeanDefinition​

​​方法,很顯然是​

​AnnotationConfigApplicationContext​

​​類繼承了父類​

​GenericApplicationContext​

​​的​

​registerBeanDefinition​

​方法。

@Override
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

    this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
  }      

​GenericApplicationContext​

​​類的​

​beanFactory​

​​屬性是​

​DefaultListableBeanFactory​

​類的執行個體。

private final DefaultListableBeanFactory beanFactory;      

​DefaultListableBeanFactory​

​​類是​

​Spring​

​​預設實作的​

​ConfigurableListableBeanFactory​

​​和​

​BeanDefinitionRegistry​

​​接口:一個基于​

​bean definition​

​​中繼資料的成熟​

​bean factory​

​。

先不糾結這些類的作用,類太多了,無法把所有類的作用和原理都了解的一清二楚,需要關注的是​

​DefaultListableBeanFactory​

​​類中的​

​beanDefinitionMap​

​​和​

​beanDefinitionNames​

​​屬性,很顯然它們存儲了​

​beanName​

​​以及相關​

​BeanDefinition​

​執行個體的資訊。

/** BeanDefinition對象的映射,bean名稱為key */
  private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
  /** 按注冊順序列出BeanDefinition名稱 */
  private volatile List<String> beanDefinitionNames = new ArrayList<>(256);      

下一步調用了​

​DefaultListableBeanFactory​

​​類中的​

​registerBeanDefinition​

​​方法,在該方法中,将​

​beanName​

​​和​

​beanDefinition​

​​資訊存儲到了​

​beanDefinitionMap​

​​和​

​beanDefinitionNames​

​屬性中:

@Override
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
        ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
            "Validation of bean definition failed", ex);
      }
    }

    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
        throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
      else if (existingDefinition.getRole() < beanDefinition.getRole()) {
        // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
        if (logger.isInfoEnabled()) {
          logger.info("Overriding user-defined bean definition for bean '" + beanName +
              "' with a framework-generated bean definition: replacing [" +
              existingDefinition + "] with [" + beanDefinition + "]");
        }
      }
      else if (!beanDefinition.equals(existingDefinition)) {
        if (logger.isDebugEnabled()) {
          logger.debug("Overriding bean definition for bean '" + beanName +
              "' with a different definition: replacing [" + existingDefinition +
              "] with [" + beanDefinition + "]");
        }
      }
      else {
        if (logger.isTraceEnabled()) {
          logger.trace("Overriding bean definition for bean '" + beanName +
              "' with an equivalent definition: replacing [" + existingDefinition +
              "] with [" + beanDefinition + "]");
        }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    else {
      if (hasBeanCreationStarted()) {
        // Cannot modify startup-time collection elements anymore (for stable iteration)
        synchronized (this.beanDefinitionMap) {
          this.beanDefinitionMap.put(beanName, beanDefinition);
          List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
          updatedDefinitions.addAll(this.beanDefinitionNames);
          updatedDefinitions.add(beanName);
          this.beanDefinitionNames = updatedDefinitions;
          removeManualSingletonName(beanName);
        }
      }
      else {
        // Still in startup registration phase
        this.beanDefinitionMap.put(beanName, beanDefinition);
        this.beanDefinitionNames.add(beanName);
        removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
    }
    else if (isConfigurationFrozen()) {
      clearByTypeCache();
    }
  }      

這​

​4​

​​個内置​

​bean​

​​的​

​BeanDefinition​

​就完成了注冊。

為什麼會注冊這些内置​

​bean​

​?可以看一下調用鍊:

Spring Framework 源碼閱讀(二):BeanDefinition的作用

先是在​

​main​

​​方法中調用了​

​AnnotationConfigApplicationContext​

​類的構造函數:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
  }      

又接着調用了​

​AnnotationConfigApplicationContext​

​類的無參構造函數:

public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
  }      

然後連續調用了​

​AnnotatedBeanDefinitionReader​

​類的兩個構造函數:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
  }      
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  }      

從這裡就開始注冊内置​

​bean​

​​的​

​BeanDefinition​

​了。

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);      

接着會注冊​

​application bean​

​​的​

​BeanDefinition​

​,調用鍊如下圖所示:

Spring Framework 源碼閱讀(二):BeanDefinition的作用
Spring Framework 源碼閱讀(二):BeanDefinition的作用
@Override
  public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    this.reader.register(componentClasses);
  }      

在調用鍊的​

​doRegisterBean​

​​方法中可以發現​

​application bean​

​​的​

​BeanDefinition​

​​是​

​AnnotatedGenericBeanDefinition​

​​(​

​GenericBeanDefinition​

​​的子類)執行個體,明顯和内置​

​bean​

​​的​

​RootBeanDefinition​

​執行個體不一樣。

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }

    abd.setInstanceSupplier(supplier);
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
        if (Primary.class == qualifier) {
          abd.setPrimary(true);
        }
        else if (Lazy.class == qualifier) {
          abd.setLazyInit(true);
        }
        else {
          abd.addQualifier(new AutowireCandidateQualifier(qualifier));
        }
      }
    }
    if (customizers != null) {
      for (BeanDefinitionCustomizer customizer : customizers) {
        customizer.customize(abd);
      }
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }      

可以回顧一下部落客對​

​RootBeanDefinition​

​的介紹:

​RootBeanDefinition​

​​表示在運作時支援​

​Spring BeanFactory​

​​中特定​

​bean​

​​的合并​

​BeanDefinition​

​​。​

​RootBeanDefinition​

​​本質上是運作時的統一​

​BeanDefinition​

​視圖。

​RootBeanDefinition​

​​也可用于在配置階段注冊單個​

​BeanDefinition​

​​。然而,自​

​Spring2.5​

​​以來,以程式設計方式注冊​

​BeanDefinition​

​​的首選方法是​

​GenericBeanDefinition​

​類。

部落客的了解:因為内置​

​bean​

​​沒有父​

​bean​

​​,繼承關系是明确的,是以内置​

​bean​

​​的​

​BeanDefinition​

​​也不會有父​

​BeanDefinition​

​​,也就不需要進行合并​

​BeanDefinition​

​​的操作,此時的​

​BeanDefinition​

​​就是内置​

​bean​

​​的統一​

​BeanDefinition​

​​視圖,是以可以直接是​

​RootBeanDefinition​

​執行個體。

而​

​application bean​

​​是使用者自定義的​

​bean​

​​,繼承關系并不明确,是有可能存在繼承關系的,是以有可能需要進行合并​

​BeanDefinition​

​​的操作,此時的​

​BeanDefinition​

​​就不一定是​

​application bean​

​​的統一​

​BeanDefinition​

​​視圖,是以定義為​

​AnnotatedGenericBeanDefinition​

​​執行個體,以便之後可以進行合并​

​BeanDefinition​

​​的操作(通過設定​

​parentName​

​​)。而什麼時候會進行合并​

​BeanDefinition​

​的操作,下面會進行介紹。

​test​

​​以及​

​message bean​

​​的​

​BeanDefinition​

​都是在如下圖所示的調用鍊中被定義:

Spring Framework 源碼閱讀(二):BeanDefinition的作用
Spring Framework 源碼閱讀(二):BeanDefinition的作用

現在所有​

​bean​

​​的​

​BeanDefinition​

​​都被注冊了,下面介紹合并​

​BeanDefinition​

​。

源碼分析 - 合并​

​BeanDefinition​

合并​

​BeanDefinition​

​​的操作,在​

​bean​

​​需要執行個體化之前會被執行,如​

​AbstractBeanFactory​

​​抽象類的​

​doGetBean​

​方法(删除了不相關的代碼):

protected <T> T doGetBean(
      String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
      throws BeansException {
      try {
        RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        checkMergedBeanDefinition(mbd, beanName, args);
      }
      catch (BeansException ex) {
        cleanupAfterBeanCreationFailure(beanName);
        throw ex;
      }
    }
  }      

接着調用了​

​AbstractBeanFactory​

​​抽象類的​

​getMergedLocalBeanDefinition​

​方法:

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null && !mbd.stale) {
      return mbd;
    }
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
  }      

​AbstractBeanFactory​

​​抽象類的​

​mergedBeanDefinitions​

​​屬性是一個​

​ConcurrentHashMap​

​​執行個體,存儲了以​

​bean​

​​名稱為​

​key​

​​,合并的​

​RootBeanDefinition​

​​為​

​value​

​的鍵值對。

/** 從bean名稱映射到合并的RootBeanDefinition */
  private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);      

​RootBeanDefinition​

​​類中的​

​stale​

​​屬性,使用​

​volatile​

​修飾符修飾,保證了可見性。

/** 确定是否需要重新合并BeanDefinition */
  volatile boolean stale;      

如果之前沒有合并過,或者需要重新合并,就會調用​

​AbstractBeanFactory​

​​抽象類的​

​getMergedBeanDefinition​

​​方法,而先會調用​

​DefaultListableBeanFactory​

​​類的​

​getBeanDefinition​

​​方法擷取​

​beanName​

​​對應的​

​BeanDefinition​

​:

public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
    BeanDefinition bd = this.beanDefinitionMap.get(beanName);
    if (bd == null) {
      if (logger.isTraceEnabled()) {
        logger.trace("No bean named '" + beanName + "' found in " + this);
      }
      throw new NoSuchBeanDefinitionException(beanName);
    }
    return bd;
  }      

通過源碼,其實可以發現該​

​this​

​​(​

​DefaultListableBeanFactory​

​​執行個體)就是之前說的在​

​main​

​​方法中建立的​

​AnnotationConfigApplicationContext​

​​執行個體的​

​beanFactory​

​屬性。

Spring Framework 源碼閱讀(二):BeanDefinition的作用
Spring Framework 源碼閱讀(二):BeanDefinition的作用

在調用​

​AbstractApplicationContext​

​​類的​

​refresh​

​​方法時,将​

​AnnotationConfigApplicationContext​

​​執行個體的​

​beanFactory​

​屬性傳進去了(删除了部分代碼):

@Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      prepareRefresh();
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      prepareBeanFactory(beanFactory);
      try {
        postProcessBeanFactory(beanFactory);
        invokeBeanFactoryPostProcessors(beanFactory);
        registerBeanPostProcessors(beanFactory);
        initMessageSource();
        initApplicationEventMulticaster();
        onRefresh();
        registerListeners();
        finishBeanFactoryInitialization(beanFactory);
        finishRefresh();
      }
    }
  }      
Spring Framework 源碼閱讀(二):BeanDefinition的作用

是以調用​

​DefaultListableBeanFactory​

​​類的​

​getBeanDefinition​

​​方法就是擷取之前定義的​

​BeanDefinition​

​​(通過​

​beanName​

​​,内置​

​bean​

​​對應​

​RootBeanDefinition​

​​執行個體,而自定義​

​bean​

​​對應​

​GenericBeanDefinition​

​執行個體)。

BeanDefinition bd = this.beanDefinitionMap.get(beanName);      

擷取​

​beanName​

​​對應的​

​BeanDefinition​

​​後,傳回到​

​AbstractBeanFactory​

​​抽象類的​

​getMergedBeanDefinition​

​方法(方法命名相同,和之前不是一樣的方法):

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
      throws BeanDefinitionStoreException {

    return getMergedBeanDefinition(beanName, bd, null);
  }      

又繼續調用​

​AbstractBeanFactory​

​​抽象類的​

​getMergedBeanDefinition​

​方法(方法命名相同,和之前不是一樣的方法):

protected RootBeanDefinition getMergedBeanDefinition(
      String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
      throws BeanDefinitionStoreException {

        // 合并BeanDefinition時需要上鎖,避免發生線程安全問題
    synchronized (this.mergedBeanDefinitions) {
      RootBeanDefinition mbd = null;
      RootBeanDefinition previous = null;
      if (containingBd == null) {
        mbd = this.mergedBeanDefinitions.get(beanName);
      }
      // 沒有合并過或者需要重新合并BeanDefinition
      if (mbd == null || mbd.stale) {
        previous = mbd;
        // 沒有父BeanDefinition,不需要合并,将原有的BeanDefinition拷貝即可
        if (bd.getParentName() == null) {
          if (bd instanceof RootBeanDefinition) {
            mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
          }
          // 非RootBeanDefinition執行個體,可能是GenericBeanDefinition類或其子類的執行個體
          else {
            mbd = new RootBeanDefinition(bd);
          }
        }
        // 有父BeanDefinition,需要合并
        else {
          BeanDefinition pbd;
          try {
            String parentBeanName = transformedBeanName(bd.getParentName());
            if (!beanName.equals(parentBeanName)) {
                // 合并父BeanDefinition
              pbd = getMergedBeanDefinition(parentBeanName);
            }
            else {
              BeanFactory parent = getParentBeanFactory();
              if (parent instanceof ConfigurableBeanFactory) {
                  // 合并父BeanDefinition
                pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
              }
              else {
                throw new NoSuchBeanDefinitionException(parentBeanName,
                    "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
                    "': cannot be resolved without a ConfigurableBeanFactory parent");
              }
            }
          }
          catch (NoSuchBeanDefinitionException ex) {
            throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
                "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
          }
          // 将合并的父BeanDefinition轉換成RootBeanDefinition執行個體
          mbd = new RootBeanDefinition(pbd);
          // 子BeanDefinition重寫合并的父BeanDefinition得到合并的子BeanDefinition
          mbd.overrideFrom(bd);
        }
        // 作用域為""時(預設),會被替代為SCOPE_SINGLETON(單例),和上面說的對應起來了
        if (!StringUtils.hasLength(mbd.getScope())) {
          mbd.setScope(SCOPE_SINGLETON);
        }
        // 非單例bean中包含的bean本身不能是單例bean
                // 更正這個問題,因為這可能是外部bean的父子合并,在這種情況下,原始内部BeanDefinition将不會繼承合并的外部bean的單例狀态。
        if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
          mbd.setScope(containingBd.getScope());
        }
        // 暫時緩存合并的BeanDefinition
                // 以後可能會重新合并,以擷取中繼資料更改
        if (containingBd == null && isCacheBeanMetadata()) {
          this.mergedBeanDefinitions.put(beanName, mbd);
        }
      }
      if (previous != null) {
        copyRelevantMergedBeanDefinitionCaches(previous, mbd);
      }
      return mbd;
    }
  }      

可見合并的​

​BeanDefinition​

​​預設就是​

​RootBeanDefinition​

​​執行個體,這也就是為什麼說​

​RootBeanDefinition​

​​本質上是運作時的統一​

​BeanDefinition​

​​視圖的原因了。該方法通過遞歸調用的形式合并​

​BeanDefinition​

​​,這也符合​

​bean​

​之間的繼承關系圖。