SpringBoot源碼系列文章
SpringBoot源碼解析(一):SpringApplication構造方法
SpringBoot源碼解析(二):引導上下文DefaultBootstrapContext
SpringBoot源碼解析(三):啟動開始階段
SpringBoot源碼解析(四):解析應用參數args
SpringBoot源碼解析(五):準備應用環境
SpringBoot源碼解析(六):打印Banner
SpringBoot源碼解析(七):應用上下文結構體系
SpringBoot源碼解析(八):Bean工廠接口體系
SpringBoot源碼解析(九):Bean定義接口體系
目錄
- 前言
- 一、BeanDefinition類圖
- 二、BeanDefinition組件功能解析
- 1、AttributeAccessor(屬性訪問器)
- 2、BeanDefinition(Bean定義)
- 3、AttributeAccessorSupport(屬性訪問器支持類)
- 4、BeanMetadataAttributeAccessor(Bean元數據屬性訪問器)
- 5、AbstractBeanDefinition(抽象Bean定義)
- 6、GenericBeanDefinition(通用Bean定義)
- 7、ChildBeanDefinition(子Bean定義)
- 8、RootBeanDefinition(根Bean定義)
- 9、AnnotatedBeanDefinition(注解Bean定義)
- 10、ScannedGenericBeanDefinition(掃描通用Bean定義)
- 總結
前言
??Spring容器的核心在于其對Bean的管理
,而這一切的基礎則由BeanDefinition
接口體系所支撐。BeanDefinition作為描述
和定義
Spring容器中Bean的核心接口,它不僅負責存儲Bean的元數據,還為容器的實例化、依賴注入和生命周期管理提供了必要的信息。接下來我們將對其主要組件進行介紹。
一、BeanDefinition類圖
二、BeanDefinition組件功能解析
1、AttributeAccessor(屬性訪問器)
??AttributeAccessor
是一個用于管理和操作鍵值對
形式屬性的接口,提供設置
、獲取
、刪除
、檢查屬性等通用功能,廣泛應用于Spring框架中元數據的管理
。
public interface AttributeAccessor {// 設置屬性void setAttribute(String name, @Nullable Object value);// 獲取指定屬性的值 @NullableObject getAttribute(String name);// 如果該鍵對應的屬性值已經存在,則直接返回現有值// 如果不存在,使用計算函數生成新值(相當于延遲計算,調用時候才計算)@SuppressWarnings("unchecked")default <T> T computeAttribute(String name, Function<String, T> computeFunction) {...}// 移除指定鍵的屬性并返回其值@NullableObject removeAttribute(String name);// 檢查指定鍵的屬性是否存在boolean hasAttribute(String name);// 返回所有屬性的鍵名稱String[] attributeNames();
}
2、BeanDefinition(Bean定義)
??AttributeAccessor
是一個用于管理和操作鍵值對
形式屬性的接口,提供設置
、獲取
、刪除
、檢查屬性等通用功能,廣泛應用于Spring框架中元數據的管理
。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {// 單例作用域標識符:`singleton`(表示該 Bean 在整個容器生命周期內只有一個實例)String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;// 原型作用域標識符:`prototype`(表示每次獲取該 Bean 時都會創建一個新實例)String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;// 角色:應用程序 Bean(用于實現具體的業務邏輯)int ROLE_APPLICATION = 0;// 角色:支持 Bean(一些配合主邏輯使用的輔助工具或配置類)int ROLE_SUPPORT = 1;// 角色:基礎設施 Bean(框架內部的實現類,比如事務管理器或事件監聽器,這些 Bean 通常由 Spring 自動生成,用戶無需關心)int ROLE_INFRASTRUCTURE = 2;// ==================== 可修改的屬性 ====================// 設置父定義的名稱(如果有)void setParentName(@Nullable String parentName);// 返回父定義的名稱(如果有)@NullableString getParentName();// 設置此 Bean 定義的類名void setBeanClassName(@Nullable String beanClassName);// 返回當前的 Bean 類名@NullableString getBeanClassName();// 設置 Bean 的作用域(如 singleton 或 prototype)void setScope(@Nullable String scope);// 返回 Bean 當前的作用域@NullableString getScope();// 設置是否延遲初始化(僅適用于單例 Bean)void setLazyInit(boolean lazyInit);// 返回該Bean是否延遲初始化(該Bean實際需要使用時才會被創建)boolean isLazyInit();// 設置此Bean依賴的其他 Bean 名稱(Spring容器將確保這些依賴的Bean先被初始化)void setDependsOn(@Nullable String... dependsOn);// 返回此 Bean 依賴的其他 Bean 名稱@NullableString[] getDependsOn();// 設置此 Bean 是否可以作為自動裝配的候選對象// 即:是否能夠被Spring容器在自動裝配過程中選中并注入到其他Bean中void setAutowireCandidate(boolean autowireCandidate);// 返回此 Bean 是否可以作為自動裝配的候選對象boolean isAutowireCandidate();// 設置此 Bean 是否為主要的自動裝配候選對象(在多個候選對象中優先選擇primary候選)void setPrimary(boolean primary);// 返回此 Bean 是否為主要的自動裝配候選對象boolean isPrimary();// 指定用于創建此 Bean 的工廠 Bean 名稱(如果有)void setFactoryBeanName(@Nullable String factoryBeanName);// 返回用于創建此 Bean 的工廠 Bean 名稱(如果有)@NullableString getFactoryBeanName();// 指定用于創建此 Bean 的工廠方法名稱(如果有)void setFactoryMethodName(@Nullable String factoryMethodName);// 返回用于創建此 Bean 的工廠方法名稱(如果有)@NullableString getFactoryMethodName();// 返回此 Bean 的構造函數參數值ConstructorArgumentValues getConstructorArgumentValues();// 檢查是否為此 Bean 定義了構造函數參數值default boolean hasConstructorArgumentValues() {return !getConstructorArgumentValues().isEmpty();}// 返回當前 Bean 定義中的屬性鍵值對集合,用于描述 Bean 初始化時需要注入的屬性MutablePropertyValues getPropertyValues();// 檢查是否為此 Bean 定義了屬性值default boolean hasPropertyValues() {return !getPropertyValues().isEmpty();}// 設置初始化方法名稱void setInitMethodName(@Nullable String initMethodName);// 返回初始化方法名稱@NullableString getInitMethodName();// 設置銷毀方法名稱void setDestroyMethodName(@Nullable String destroyMethodName);// 返回銷毀方法名稱@NullableString getDestroyMethodName();// 設置此 Bean 定義的角色,上面常量的三種角色void setRole(int role);// 返回此 Bean 定義的角色int getRole();// 設置此 Bean 定義的人類可讀描述void setDescription(@Nullable String description);// 返回此 Bean 定義的人類可讀描述@NullableString getDescription();// ==================== 只讀屬性 ====================// 解析和返回當前 Bean 定義的具體類型(包括泛型和復雜類型)ResolvableType getResolvableType();// 檢查此 Bean 是否為單例boolean isSingleton();// 檢查此 Bean 是否為原型boolean isPrototype();// 判斷一個 Bean 定義是否為抽象定義,用于區分模板和具體實現boolean isAbstract();// 返回 Bean 定義的資源描述(通常是 XML 文件、Java 配置類、注解等)// 通過返回的描述,開發者可以了解這個 Bean 是從哪里加載的,便于定位問題@NullableString getResourceDescription();// 它的作用是在Bean定義發生裝飾、代理或重新定義時,提供對原始定義的訪問@NullableBeanDefinition getOriginatingBeanDefinition();
}
3、AttributeAccessorSupport(屬性訪問器支持類)
??AttributeAccessorSupport
是Spring中的一個抽象類
,用于管理任意鍵值對屬性
,提供添加、獲取、移除等操作,常用于存儲元數據
或動態屬性信息
。。
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {// 提供了一個內置的Map(attributes)來存儲鍵值對屬性private final Map<String, Object> attributes = new LinkedHashMap<>();// ...省略AttributeAccessor屬性設置獲取移除等方法的實現
}
4、BeanMetadataAttributeAccessor(Bean元數據屬性訪問器)
??BeanMetadataAttributeAccessor
是Spring框架中一個常用的工具類。它用于存儲和管理與Bean元數據相關的附加屬性
,尤其是在Spring容器中擴展Bean定義時,作為元數據的容器。
@SuppressWarnings("serial")
public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {// 記錄元數據元素的來源對象,可以是配置文件路徑、注解類等@Nullableprivate Object source;// 設置此元數據元素的配置來源對象public void setSource(@Nullable Object source) {this.source = source;}// 獲取此元數據元素的配置來源對象@Override@Nullablepublic Object getSource() {return this.source;}// 將給定的BeanMetadataAttribute添加到此訪問器的屬性集中public void addMetadataAttribute(BeanMetadataAttribute attribute) {// 將屬性存儲在父類提供的 attributes Map 中super.setAttribute(attribute.getName(), attribute);}// 在此訪問器的屬性集中查找給定的BeanMetadataAttribute@Nullablepublic BeanMetadataAttribute getMetadataAttribute(String name) {return (BeanMetadataAttribute) super.getAttribute(name);}// 設置屬性,將其包裝為BeanMetadataAttribute存儲@Overridepublic void setAttribute(String name, @Nullable Object value) {// 將屬性值包裝為 BeanMetadataAttributesuper.setAttribute(name, new BeanMetadataAttribute(name, value));}// 獲取指定名稱的屬性值@Override@Nullablepublic Object getAttribute(String name) {// 從父類的 attributes Map 獲取 BeanMetadataAttributeBeanMetadataAttribute attribute = (BeanMetadataAttribute) super.getAttribute(name);// 返回其值return (attribute != null ? attribute.getValue() : null);}// 移除指定名稱的屬性并返回其值@Override@Nullablepublic Object removeAttribute(String name) {// 從父類的 attributes Map 移除 BeanMetadataAttributeBeanMetadataAttribute attribute = (BeanMetadataAttribute) super.removeAttribute(name);// 返回其值return (attribute != null ? attribute.getValue() : null);}
}
5、AbstractBeanDefinition(抽象Bean定義)
??AbstractBeanDefinition
是Spring中Bean定義
的抽象基類
,提供了描述Bean的屬性、依賴關系、作用域和生命周期等核心功能。
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessorimplements BeanDefinition, Cloneable {// ==================== 核心屬性 ====================// Bean的類對象,可以是Class實例或類名字符串@Nullableprivate volatile Object beanClass; // SCOPE_DEFAULT: 默認的Bean作用域名稱為 "",等效于單例狀態,除非被父Bean定義覆蓋@Nullableprivate String scope = SCOPE_DEFAULT; // 標記該Bean是否為抽象Bean,抽象Bean不能被實例化private boolean abstractFlag = false; // 是否延遲初始化,null表示未明確設置@Nullableprivate Boolean lazyInit; // 自動裝配模式,默認不自動裝配private int autowireMode = AUTOWIRE_NO; // 依賴檢查模式,默認無依賴檢查private int dependencyCheck = DEPENDENCY_CHECK_NONE; // 該Bean依賴的其他Bean名稱@Nullableprivate String[] dependsOn; // 是否為自動裝配候選Beanprivate boolean autowireCandidate = true; // 是否為主要的自動裝配候選Beanprivate boolean primary = false; // 工廠Bean的名稱,如果通過工廠Bean創建@Nullableprivate String factoryBeanName; // 工廠方法的名稱,用于通過靜態方法或工廠Bean的方法創建實例@Nullableprivate String factoryMethodName; // 構造函數的參數值@Nullableprivate ConstructorArgumentValues constructorArgumentValues; // Bean的屬性值@Nullableprivate MutablePropertyValues propertyValues; // 初始化方法名稱,用于在Bean實例化后調用@Nullableprivate String initMethodName; // 銷毀方法名稱,用于在Bean銷毀前調用@Nullableprivate String destroyMethodName; // Bean的角色,默認是應用角色private int role = BeanDefinition.ROLE_APPLICATION; // Bean的描述信息@Nullableprivate String description; // 描述該Bean定義來源的資源,例如XML配置文件的位置@Nullableprivate Resource resource; // ==================== 核心方法 ====================// 都是類似的getset方法@Overridepublic void setBeanClassName(@Nullable String beanClassName) {this.beanClass = beanClassName;}@Override@Nullablepublic String getBeanClassName() {Object beanClassObject = this.beanClass;if (beanClassObject instanceof Class) {return ((Class<?>) beanClassObject).getName();}else {return (String) beanClassObject;}}// 驗證 Bean 定義是否有效,例如檢查必須的屬性是否已設置public void validate() throws BeanDefinitionValidationException {...}// 克隆當前 Bean 定義,用于 Bean 配置的復制public abstract AbstractBeanDefinition cloneBeanDefinition();
}
6、GenericBeanDefinition(通用Bean定義)
??GenericBeanDefinition
用于定義普通的Bean配置,適用于沒有繼承關系的獨立Bean(雖然可以指定父 Bean,但通常不表示父子關系),支持配置構造方法、作用域、初始化方法等屬性。
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {@Nullableprivate String parentName; // 父類名稱// 創建一個新的GenericBeanDefinition// 可通過其bean屬性和配置方法進行配置public GenericBeanDefinition() {super();}// 創建一個新的GenericBeanDefinition,作為給定bean定義的深拷貝public GenericBeanDefinition(BeanDefinition original) {super(original);}// 設置父類名稱@Overridepublic void setParentName(@Nullable String parentName) {this.parentName = parentName; }// 獲取父類名稱@Override@Nullablepublic String getParentName() {return this.parentName; }// 克隆 bean 定義@Overridepublic AbstractBeanDefinition cloneBeanDefinition() {return new GenericBeanDefinition(this); }// ... 省略重寫 equal 和 toString方法
}
7、ChildBeanDefinition(子Bean定義)
??ChildBeanDefinition
專門用于表示子Bean的定義,允許子bean繼承父bean的屬性和方法
,并可以進行擴展或覆蓋。
@SuppressWarnings("serial")
public class ChildBeanDefinition extends AbstractBeanDefinition {@Nullableprivate String parentName; // 父類名稱// 為給定的父類創建一個新的 ChildBeanDefinition,提供構造函數參數和屬性值public ChildBeanDefinition(String parentName, Class<?> beanClass, ConstructorArgumentValues cargs, MutablePropertyValues pvs) {super(cargs, pvs);this.parentName = parentName; // 設置父類名稱setBeanClass(beanClass); // 設置 bean 類}// ... 省略類似構造方法// 設置父類名稱@Overridepublic void setParentName(@Nullable String parentName) {this.parentName = parentName; }// 獲取父類名稱@Override@Nullablepublic String getParentName() {return this.parentName; }// 校驗父類必須存在,否則報錯@Overridepublic void validate() throws BeanDefinitionValidationException {super.validate();// 校驗父類名稱是否為空if (this.parentName == null) {throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");}}// 克隆當前的 ChildBeanDefinition@Overridepublic AbstractBeanDefinition cloneBeanDefinition() {return new ChildBeanDefinition(this); }// ... 省略重寫 equal 和 toString方法
}
8、RootBeanDefinition(根Bean定義)
??RootBeanDefinition
用于定義容器中的根級Bean
配置,不能繼承父Bean,是獨立的頂級Bean定義類。
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {// 此屬性用于保存一個被該bean定義裝飾增強的Bean定義@Nullableprivate BeanDefinitionHolder decoratedDefinition; // Bean定義的注解信息@Nullableprivate AnnotatedElement qualifiedElement; ...// 目標類型,表示包含泛型的類型@Nullablevolatile ResolvableType targetType; // 緩存解析后的目標類型@Nullablevolatile Class<?> resolvedTargetType;// 緩存已解析的銷毀方法的名稱@Nullablevolatile String resolvedDestroyMethodName;// 緩存解析后的構造函數或工廠方法@NullableExecutable resolvedConstructorOrFactoryMethod;// 緩存完全解析的構造函數參數@NullableObject[] resolvedConstructorArguments;...// 創建一個新的 RootBeanDefinition,通過其 bean 屬性和配置方法進行配置public RootBeanDefinition() {super();}// 創建一個新的RootBeanDefinition用于帶有作用域的bean,通過給定的supplier構造每個實例public <T> RootBeanDefinition(@Nullable Class<T> beanClass, String scope, @Nullable Supplier<T> instanceSupplier) {super();setBeanClass(beanClass);setScope(scope);setInstanceSupplier(instanceSupplier);}// ...省略其他構造方法// 省略了一些其他注釋,以節省篇幅// 克隆 RootBeanDefinition@Overridepublic RootBeanDefinition cloneBeanDefinition() {return new RootBeanDefinition(this); }// ... 省略重寫 equal 和 toString方法
}
9、AnnotatedBeanDefinition(注解Bean定義)
??AnnotatedBeanDefinition
是一個擴展了BeanDefinition
的接口,用于訪問與Bean類相關的注解元數據
,如類級注解和工廠方法的元數據。
public interface AnnotatedBeanDefinition extends BeanDefinition {// 獲取當前Bean類的注解信息,允許在不加載類的情況下訪問類級注解元數據AnnotationMetadata getMetadata();// 返回當前 Bean 定義的工廠方法的元數據,如果沒有工廠方法則返回 null@NullableMethodMetadata getFactoryMethodMetadata();
}
10、ScannedGenericBeanDefinition(掃描通用Bean定義)
??ScannedGenericBeanDefinition
是Spring中用于表示通過類路徑掃描(如 @ComponentScan
)發現的Bean的定義類,包含了掃描到的Bean類的元數據和配置信息。
// 該類不會在早期加載Bean的Class,而是從 ".class" 文件本身解析所有相關的元數據,
// 使用 ASM ClassReader 進行解析
@SuppressWarnings("serial")
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {// 存儲掃描到的 Bean 類的注解元數據private final AnnotationMetadata metadata;// 為給定的 MetadataReader 描述的類創建一個新的 ScannedGenericBeanDefinition。public ScannedGenericBeanDefinition(MetadataReader metadataReader) {// 校驗 metadataReader 不為 nullAssert.notNull(metadataReader, "MetadataReader must not be null");// 從 MetadataReader 獲取注解元數據this.metadata = metadataReader.getAnnotationMetadata();// 設置 Bean 類的名稱setBeanClassName(this.metadata.getClassName());// 設置掃描到的資源setResource(metadataReader.getResource());}@Override// 返回 Bean 類的注解元數據public final AnnotationMetadata getMetadata() {return this.metadata;}@Override@Nullable// 返回工廠方法的元數據(這里為 null,表示沒有工廠方法)public MethodMetadata getFactoryMethodMetadata() {return null;}
}
總結
??本文詳細介紹了Spring框架中Bean的定義
及其管理機制,重點闡述了BeanDefinition
接口及其各個實現類的功能,包括屬性訪問
、Bean元數據管理
、父子Bean關系
、作用域
、依賴注入
等方面的實現,旨在幫助開發者理解Spring容器如何通過這些機制來管理和配置Bean的生命周期。