亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring核心容器之BeanDefinition解析

 更新時(shí)間:2023年11月16日 11:11:30   作者:龍三丶  
這篇文章主要介紹了Spring核心容器之BeanDefinition解析,Spring 將管理的對象稱之為 Bean,容器會(huì)先實(shí)例化 Bean,然后自動(dòng)注入,實(shí)例化的過程就需要依賴 BeanDefinition,需要的朋友可以參考下

前言

現(xiàn)如今,我們一般獲取對象的方式有兩種,一種是手動(dòng)直接 new;另一種是交給 Spring 管理,Spring 將管理的對象稱之為 Bean,容器會(huì)先實(shí)例化 Bean,然后自動(dòng)注入,實(shí)例化的過程就需要依賴 BeanDefinition。

BeanDefinition 用于保存 Bean 的相關(guān)信息,包括屬性、構(gòu)造方法參數(shù)、依賴的 Bean 名稱及是否單例、延遲加載等,它是實(shí)例化 Bean 的原材料,Spring 就是根據(jù) BeanDefinition 中的信息實(shí)例化 Bean。

BeanDefinition的繼承體系

BeanDefinition 是一個(gè)接口,它有多個(gè)實(shí)現(xiàn)類,這些實(shí)現(xiàn)類分別描述不同類型的 Bean。

image

BeanDefinition

一個(gè) BeanDefinition 描述了一個(gè) Bean 實(shí)例,實(shí)例包含屬性值、構(gòu)造方法參數(shù)值以及更多實(shí)現(xiàn)信息。該 BeanDefinition 只是是一個(gè)最小的接口,主要目的是允許修改屬性值和其他 Bean 元數(shù)據(jù),這里列出幾個(gè)核心方法。

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	// 單例、原型標(biāo)識(shí)符
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

    // 標(biāo)識(shí) Bean 的類別,分別對應(yīng) 用戶定義的 Bean、來源于配置文件的 Bean、Spring 內(nèi)部的 Bean
	int ROLE_APPLICATION = 0;
	int ROLE_SUPPORT = 1;
	int ROLE_INFRASTRUCTURE = 2;

    // 設(shè)置、返回 Bean 的父類名稱
	void setParentName(@Nullable String parentName);
	String getParentName();

    // 設(shè)置、返回 Bean 的 className
	void setBeanClassName(@Nullable String beanClassName);
	String getBeanClassName();

    // 設(shè)置、返回 Bean 的作用域
	void setScope(@Nullable String scope);
	String getScope();

    // 設(shè)置、返回 Bean 是否懶加載
	void setLazyInit(boolean lazyInit);
	boolean isLazyInit();
	
	// 設(shè)置、返回當(dāng)前 Bean 所依賴的其它 Bean 名稱。
	void setDependsOn(@Nullable String... dependsOn);
	String[] getDependsOn();
	
	// 設(shè)置、返回 Bean 是否可以自動(dòng)注入。只對 @Autowired 注解有效
	void setAutowireCandidate(boolean autowireCandidate);
	boolean isAutowireCandidate();
	
	// 設(shè)置、返回當(dāng)前 Bean 是否為主要候選 Bean 。
	// 當(dāng)同一個(gè)接口有多個(gè)實(shí)現(xiàn)類時(shí),通過該屬性來配置某個(gè) Bean 為主候選 Bean。
	void setPrimary(boolean primary);
	boolean isPrimary();

    // 設(shè)置、返回創(chuàng)建該 Bean 的工廠類。
	void setFactoryBeanName(@Nullable String factoryBeanName);
	String getFactoryBeanName();
	
	// 設(shè)置、返回創(chuàng)建該 Bean 的工廠方法
	void setFactoryMethodName(@Nullable String factoryMethodName);
	String getFactoryMethodName();
	
	// 返回該 Bean 構(gòu)造方法參數(shù)值、所有屬性
	ConstructorArgumentValues getConstructorArgumentValues();
	MutablePropertyValues getPropertyValues();

    // 返回該 Bean 是否是單例、是否是非單例、是否是抽象的
	boolean isSingleton();
	boolean isPrototype();
	boolean isAbstract();

    // 返回 Bean 的類別。類別對應(yīng)上面的三個(gè)屬性值。
	int getRole();

    ...
}

可以看到 BeanDefinition 接口提供了一系列操作 Bean 元數(shù)據(jù)的set、get方法,這些操作為 Bean 的描述定義了一套模板,具體的實(shí)現(xiàn)則交由子類。

AnnotatedBeanDefinition

AnnotatedBeanDefinition 是 BeanDefinition 子接口之一,該接口擴(kuò)展了 BeanDefinition 的功能,其用來操作注解元數(shù)據(jù)。一般情況下,通過注解方式得到的 Bean(@Component、@Bean),其 BeanDefinition 類型都是該接口的實(shí)現(xiàn)類。

public interface AnnotatedBeanDefinition extends BeanDefinition {

	// 獲得當(dāng)前 Bean 的注解元數(shù)據(jù)
	AnnotationMetadata getMetadata();

	// 獲得當(dāng)前 Bean 的工廠方法上的元數(shù)據(jù)
	MethodMetadata getFactoryMethodMetadata();
}

該接口可以返回兩個(gè)元數(shù)據(jù)的類:

  • AnnotationMetadata:主要對 Bean 的注解信息進(jìn)行操作,如:獲取當(dāng)前 Bean 標(biāo)注的所有注解、判斷是否包含指定注解。
  • MethodMetadata:方法的元數(shù)據(jù)類。提供獲取方法名稱、此方法所屬類的全類名、是否是抽象方法、判斷是否是靜態(tài)方法、判斷是否是final方法等。

AbstractBeanDefinition

AbstractBeanDefinition 是 BeanDefinition 的子抽象類,也是其他 BeanDefinition 類型的基類,其實(shí)現(xiàn)了接口中定義的一系列操作方法,并定義了一系列的常量屬性,這些常量會(huì)直接影響到 Spring 實(shí)例化 Bean 時(shí)的策略。核心屬性如下。

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {
    // 默認(rèn)的 SCOPE,默認(rèn)是單例
	public static final String SCOPE_DEFAULT = "";
	// 不進(jìn)行自動(dòng)裝配
	public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
    // 根據(jù) Bean 的名字進(jìn)行自動(dòng)裝配,byName
	public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
	// 根據(jù) Bean 的類型進(jìn)行自動(dòng)裝配,byType
	public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
	// 根據(jù)構(gòu)造器進(jìn)行自動(dòng)裝配
	public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
	// 首先嘗試按構(gòu)造器自動(dòng)裝配。如果失敗,再嘗試使用 byType 進(jìn)行自動(dòng)裝配。(Spring 3.0 之后已廢除)
	public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
    // 通過依賴檢查來查看 Bean 的每個(gè)屬性是否都設(shè)置完成
    // 以下常量分別對應(yīng):不檢查、對依賴對象檢查、對基本類型,字符串和集合進(jìn)行檢查、對全部屬性進(jìn)行檢查
	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;
	// 關(guān)閉應(yīng)用上下文時(shí)需調(diào)用的方法名稱
	public static final String INFER_METHOD = "(inferred)";
    // 存放 Bean 的 Class 對象
	private volatile Object beanClass;
	// Bean 的作用范圍
	private String scope = SCOPE_DEFAULT;
    // 非抽象
	private boolean abstractFlag = false;
	// 非延遲加載
	private boolean lazyInit = false;
    // 默認(rèn)不自動(dòng)裝配
	private int autowireMode = AUTOWIRE_NO;
    // 默認(rèn)不依賴檢查
	private int dependencyCheck = DEPENDENCY_CHECK_NONE;
	// 依賴的 Bean 列表
	private String[] dependsOn;
    // 可以作為自動(dòng)裝配的候選者,意味著可以自動(dòng)裝配到其他 Bean 的某個(gè)屬性中
	private boolean autowireCandidate = true;
	// 創(chuàng)建當(dāng)前 Bean 實(shí)例工廠類名稱
	private String factoryBeanName;
    // 創(chuàng)建當(dāng)前 Bean 實(shí)例工廠類中方法名稱
	private String factoryMethodName;
	// 存儲(chǔ)構(gòu)造方法的參數(shù)
	private ConstructorArgumentValues constructorArgumentValues;
    // 存儲(chǔ) Bean 屬性名稱以及對應(yīng)的值
	private MutablePropertyValues propertyValues;
    // 存儲(chǔ)被覆蓋的方法信息
	private MethodOverrides methodOverrides;
	// init、destroy 方法名稱
	private String initMethodName;
	private String destroyMethodName;
    // 是否執(zhí)行 init 和 destroy 方法
	private boolean enforceInitMethod = true;
	private boolean enforceDestroyMethod = true;
    // Bean 是否是用戶定義的而不是應(yīng)用程序本身定義的
	private boolean synthetic = false;
    // Bean 的身份類別,默認(rèn)是用戶定義的 Bean
	private int role = BeanDefinition.ROLE_APPLICATION;
	// Bean 的描述信息
	private String description;
	// Bean 定義的資源
	private Resource resource;
	...
}

以上是 AbstractBeanDefinition 中定義的一些常量和屬性,該類中還有一部分是操作這些屬性的 set 和 get 方法,這些方法都由子類來操作,且應(yīng)用程序中真正使用的也是這些子類 BeanDefinition。

先來看 AbstractBeanDefinition 直接實(shí)現(xiàn)類:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。

RootBeanDefinition

該類繼承自 AbstractBeanDefinition,它可以單獨(dú)作為一個(gè) BeanDefinition,也可以作為其他 BeanDefinition 的父類。

RootBeanDefinition 在 AbstractBeanDefinition 的基礎(chǔ)上定義了更多屬性。

public class RootBeanDefinition extends AbstractBeanDefinition {

    // BeanDefinitionHolder 存儲(chǔ) Bean 的名稱、別名、BeanDefinition
	private BeanDefinitionHolder decoratedDefinition;

	// AnnotatedElement 是java反射包的接口,通過它可以查看 Bean 的注解信息
	private AnnotatedElement qualifiedElement;

    // 允許緩存
	boolean allowCaching = true;
    
    // 工廠方法是否唯一
	boolean isFactoryMethodUnique = false;

	// 封裝了 java.lang.reflect.Type,提供了泛型相關(guān)的操作
	volatile ResolvableType targetType;

	// 緩存 Class,表示 RootBeanDefinition 存儲(chǔ)哪個(gè)類的信息
	volatile Class<?> resolvedTargetType;

	// 緩存工廠方法的返回類型
	volatile ResolvableType factoryMethodReturnType;

	// 這是以下四個(gè)構(gòu)造方法字段的通用鎖
	final Object constructorArgumentLock = new Object();
	// 用于緩存已解析的構(gòu)造方法或工廠方法
	Executable resolvedConstructorOrFactoryMethod;
	// 將構(gòu)造方法參數(shù)標(biāo)記為已解析
	boolean constructorArgumentsResolved = false;
	// 用于緩存完全解析的構(gòu)造方法參數(shù)
	Object[] resolvedConstructorArguments;
	// 緩存待解析的構(gòu)造方法參數(shù)
	Object[] preparedConstructorArguments;

	// 這是以下兩個(gè)后處理字段的通用鎖
	final Object postProcessingLock = new Object();
	// 表明是否被 MergedBeanDefinitionPostProcessor 處理過
	boolean postProcessed = false;
	// 在生成代理的時(shí)候會(huì)使用,表明是否已經(jīng)生成代理
	volatile Boolean beforeInstantiationResolved;

	// 實(shí)際緩存的類型是 Constructor、Field、Method 類型
	private Set<Member> externallyManagedConfigMembers;

	// InitializingBean中 的 init 回調(diào)函數(shù)名 afterPropertiesSet 會(huì)在這里記錄,以便進(jìn)行生命周期回調(diào)
	private Set<String> externallyManagedInitMethods;

	// DisposableBean 的 destroy 回調(diào)函數(shù)名 destroy 會(huì)在這里記錄,以便進(jìn)生命周期回調(diào)
	private Set<String> externallyManagedDestroyMethods;

    ...
}

ChildBeanDefinition

該類繼承自 AbstractBeanDefinition。其相當(dāng)于一個(gè)子類,不可以單獨(dú)存在,必須依賴一個(gè)父 BeanDetintion,構(gòu)造 ChildBeanDefinition 時(shí),通過構(gòu)造方法傳入父 BeanDetintion 的名稱或通過 setParentName 設(shè)置父名稱。它可以從父類繼承方法參數(shù)、屬性值,并可以重寫父類的方法,同時(shí)也可以增加新的屬性或者方法。若重新定義 init 方法,destroy 方法或者靜態(tài)工廠方法,ChildBeanDefinition 會(huì)重寫父類的設(shè)置。

從 Spring 2.5 開始,以編程方式注冊 Bean 定義的首選方法是 GenericBeanDefinition,GenericBeanDefinition 可以有效替代 ChildBeanDefinition 的絕大分部使用場合。

GenericBeanDefinition

GenericBeanDefinition 是 Spring 2.5 以后新引入的 BeanDefinition,是 ChildBeanDefinition 更好的替代者,它同樣可以通過 setParentName 方法設(shè)置父 BeanDefinition。

最后三個(gè) BeanDefinition 既實(shí)現(xiàn)了 AnnotatedBeanDefinition 接口,又間接繼承 AbstractBeanDefinition 抽象類,這些 BeanDefinition 描述的都是注解形式的 Bean。

ConfigurationClassBeanDefinition

該類繼承自 RootBeanDefinition ,并實(shí)現(xiàn)了 AnnotatedBeanDefinition 接口。這個(gè) BeanDefinition 用來描述在標(biāo)注 @Configuration 注解的類中,通過 @Bean 注解實(shí)例化的 Bean。

其功能特點(diǎn)如下:

1、如果 @Bean 注解沒有指定 Bean 的名字,默認(rèn)會(huì)用方法的名字命名 Bean。

2、標(biāo)注 @Configuration 注解的類會(huì)成為一個(gè)工廠類,而標(biāo)注 @Bean 注解的方法會(huì)成為工廠方法,通過工廠方法實(shí)例化 Bean,而不是直接通過構(gòu)造方法初始化。

3、標(biāo)注 @Bean 注解的類會(huì)使用構(gòu)造方法自動(dòng)裝配

AnnotatedGenericBeanDefinition

該類繼承自 GenericBeanDefinition ,并實(shí)現(xiàn)了 AnnotatedBeanDefinition 接口。這個(gè) BeanDefinition 用來描述標(biāo)注 @Configuration 注解的 Bean。

ScannedGenericBeanDefinition

該類繼承自 GenericBeanDefinition ,并實(shí)現(xiàn)了 AnnotatedBeanDefinition 接口。這個(gè) BeanDefinition 用來描述標(biāo)注 @Component 注解的 Bean,其派生注解如 @Service、@Controller 也同理。

總結(jié)

最后,我們來做個(gè)總結(jié)。BeanDefinition 主要是用來描述 Bean,其存儲(chǔ)了 Bean 的相關(guān)信息,Spring 實(shí)例化 Bean 時(shí)需讀取該 Bean 對應(yīng)的 BeanDefinition。

BeanDefinition 整體可以分為兩類,一類是描述通用的 Bean,還有一類是描述注解形式的 Bean。

一般前者在 XML 時(shí)期定義 <bean’> 標(biāo)簽以及在 Spring 內(nèi)部使用較多,而現(xiàn)今我們大都使用后者,通過注解形式加載 Bean。

到此這篇關(guān)于Spring核心容器之BeanDefinition解析的文章就介紹到這了,更多相關(guān)Spring的BeanDefinition解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作

    java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作

    這篇文章主要介紹了java實(shí)現(xiàn)相同屬性名稱及相似類型的pojo、dto、vo等互轉(zhuǎn)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • SpringBoot下使用MyBatis-Puls代碼生成器的方法

    SpringBoot下使用MyBatis-Puls代碼生成器的方法

    這篇文章主要介紹了SpringBoot下使用MyBatis-Puls代碼生成器的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 詳解Java項(xiàng)目中讀取properties文件

    詳解Java項(xiàng)目中讀取properties文件

    本篇文章主要介紹了Java項(xiàng)目中讀取properties文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-12-12
  • Java BigDecimal解決double精度丟失的問題

    Java BigDecimal解決double精度丟失的問題

    我們在日常開發(fā)中, 有很多時(shí)候會(huì)遇到小數(shù)(double類型)精確計(jì)算,本文主要介紹了Java BigDecimal解決double精度丟失的問題,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • Java+mysql用戶注冊登錄功能

    Java+mysql用戶注冊登錄功能

    這篇文章主要為大家詳細(xì)介紹了Java結(jié)合mysql實(shí)現(xiàn)用戶注冊登錄功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Java基于final修飾數(shù)據(jù)過程解析

    Java基于final修飾數(shù)據(jù)過程解析

    這篇文章主要介紹了Java基于final修飾數(shù)據(jù)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題

    解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題

    這篇文章主要介紹了解決SpringMVC @RequestMapping不設(shè)置value出現(xiàn)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java基于棧方式解決漢諾塔問題實(shí)例【遞歸與非遞歸算法】

    Java基于棧方式解決漢諾塔問題實(shí)例【遞歸與非遞歸算法】

    這篇文章主要介紹了Java基于棧方式解決漢諾塔問題的方法,結(jié)合實(shí)例形式分析了java棧方式采用遞歸與非遞歸算法解決漢諾塔問題的相關(guān)操作技巧,需要的朋友可以參考下
    2017-11-11
  • java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置

    java實(shí)現(xiàn)根據(jù)ip地址獲取地理位置

    本文給大家匯總介紹了2種分別使用新浪和淘寶接口,實(shí)現(xiàn)根據(jù)IP地址獲取詳細(xì)的地理位置的代碼,非常的實(shí)用,有需要的小伙伴可以參考下。
    2016-03-03
  • Spring中的依賴注入DI詳解

    Spring中的依賴注入DI詳解

    這篇文章主要介紹了Spring中的依賴注入DI詳解,組件之間依賴關(guān)系由容器在運(yùn)行期決定,形象的說,即由容器動(dòng)態(tài)的將依賴關(guān)系注入到組件之中,依賴注入的目的并非為軟件系統(tǒng)帶來更多功能,是為了提升組件重用的頻率,并為系統(tǒng)搭建一個(gè)靈活、可擴(kuò)展的平臺(tái),需要的朋友可以參考下
    2024-01-01

最新評(píng)論