最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring核心容器之BeanDefinition解析

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

前言

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

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

BeanDefinition的繼承體系

BeanDefinition 是一個(gè)接口,它有多個(gè)實(shí)現(xiàn)類(lèi),這些實(shí)現(xiàn)類(lèi)分別描述不同類(lèi)型的 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 的類(lèi)別,分別對(duì)應(yīng) 用戶定義的 Bean、來(lái)源于配置文件的 Bean、Spring 內(nèi)部的 Bean
	int ROLE_APPLICATION = 0;
	int ROLE_SUPPORT = 1;
	int ROLE_INFRASTRUCTURE = 2;

    // 設(shè)置、返回 Bean 的父類(lèi)名稱(chēng)
	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 所依賴(lài)的其它 Bean 名稱(chēng)。
	void setDependsOn(@Nullable String... dependsOn);
	String[] getDependsOn();
	
	// 設(shè)置、返回 Bean 是否可以自動(dòng)注入。只對(duì) @Autowired 注解有效
	void setAutowireCandidate(boolean autowireCandidate);
	boolean isAutowireCandidate();
	
	// 設(shè)置、返回當(dāng)前 Bean 是否為主要候選 Bean 。
	// 當(dāng)同一個(gè)接口有多個(gè)實(shí)現(xiàn)類(lèi)時(shí),通過(guò)該屬性來(lái)配置某個(gè) Bean 為主候選 Bean。
	void setPrimary(boolean primary);
	boolean isPrimary();

    // 設(shè)置、返回創(chuàng)建該 Bean 的工廠類(lèi)。
	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 的類(lèi)別。類(lèi)別對(duì)應(yīng)上面的三個(gè)屬性值。
	int getRole();

    ...
}

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

AnnotatedBeanDefinition

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

public interface AnnotatedBeanDefinition extends BeanDefinition {

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

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

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

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

AbstractBeanDefinition

AbstractBeanDefinition 是 BeanDefinition 的子抽象類(lèi),也是其他 BeanDefinition 類(lèi)型的基類(lèi),其實(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 的類(lèi)型進(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)裝配。如果失敗,再?lài)L試使用 byType 進(jìn)行自動(dòng)裝配。(Spring 3.0 之后已廢除)
	public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
    // 通過(guò)依賴(lài)檢查來(lái)查看 Bean 的每個(gè)屬性是否都設(shè)置完成
    // 以下常量分別對(duì)應(yīng):不檢查、對(duì)依賴(lài)對(duì)象檢查、對(duì)基本類(lèi)型,字符串和集合進(jìn)行檢查、對(duì)全部屬性進(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)用的方法名稱(chēng)
	public static final String INFER_METHOD = "(inferred)";
    // 存放 Bean 的 Class 對(duì)象
	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)不依賴(lài)檢查
	private int dependencyCheck = DEPENDENCY_CHECK_NONE;
	// 依賴(lài)的 Bean 列表
	private String[] dependsOn;
    // 可以作為自動(dòng)裝配的候選者,意味著可以自動(dòng)裝配到其他 Bean 的某個(gè)屬性中
	private boolean autowireCandidate = true;
	// 創(chuàng)建當(dāng)前 Bean 實(shí)例工廠類(lèi)名稱(chēng)
	private String factoryBeanName;
    // 創(chuàng)建當(dāng)前 Bean 實(shí)例工廠類(lèi)中方法名稱(chēng)
	private String factoryMethodName;
	// 存儲(chǔ)構(gòu)造方法的參數(shù)
	private ConstructorArgumentValues constructorArgumentValues;
    // 存儲(chǔ) Bean 屬性名稱(chēng)以及對(duì)應(yīng)的值
	private MutablePropertyValues propertyValues;
    // 存儲(chǔ)被覆蓋的方法信息
	private MethodOverrides methodOverrides;
	// init、destroy 方法名稱(chēng)
	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 的身份類(lèi)別,默認(rèn)是用戶定義的 Bean
	private int role = BeanDefinition.ROLE_APPLICATION;
	// Bean 的描述信息
	private String description;
	// Bean 定義的資源
	private Resource resource;
	...
}

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

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

RootBeanDefinition

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

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

public class RootBeanDefinition extends AbstractBeanDefinition {

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

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

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

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

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

	// 緩存工廠方法的返回類(lèi)型
	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 處理過(guò)
	boolean postProcessed = false;
	// 在生成代理的時(shí)候會(huì)使用,表明是否已經(jīng)生成代理
	volatile Boolean beforeInstantiationResolved;

	// 實(shí)際緩存的類(lèi)型是 Constructor、Field、Method 類(lèi)型
	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

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

從 Spring 2.5 開(kāi)始,以編程方式注冊(cè) Bean 定義的首選方法是 GenericBeanDefinition,GenericBeanDefinition 可以有效替代 ChildBeanDefinition 的絕大分部使用場(chǎng)合。

GenericBeanDefinition

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

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

ConfigurationClassBeanDefinition

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

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

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

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

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

AnnotatedGenericBeanDefinition

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

ScannedGenericBeanDefinition

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

總結(jié)

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

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

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

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

相關(guān)文章

  • 基于Java實(shí)現(xiàn)PPT到PDF的高效轉(zhuǎn)換詳解

    基于Java實(shí)現(xiàn)PPT到PDF的高效轉(zhuǎn)換詳解

    在日常開(kāi)發(fā)中,經(jīng)常會(huì)遇到將PPT文檔批量或單文件轉(zhuǎn)換為PDF的需求,本文將詳細(xì)介紹其使用流程、核心代碼與常見(jiàn)問(wèn)題解決方案,希望對(duì)大家有所幫助
    2025-11-11
  • Java反射與自定義注解實(shí)戰(zhàn)指南詳解

    Java反射與自定義注解實(shí)戰(zhàn)指南詳解

    本文介紹Java反射機(jī)制及自定義注解應(yīng)用,涵蓋反射核心類(lèi)、操作方式與性能優(yōu)化,以及注解定義、SpringBoot集成和AOP處理,強(qiáng)調(diào)二者在框架開(kāi)發(fā)中的協(xié)同作用,提升系統(tǒng)靈活性和擴(kuò)展性,感興趣的朋友跟隨小編一起看看吧
    2025-07-07
  • 利用Java巧妙解決Excel公式迭代計(jì)算

    利用Java巧妙解決Excel公式迭代計(jì)算

    迭代計(jì)算其實(shí)是在?Excel?中,一種公式的循環(huán)引用,那么如何利用Java語(yǔ)言巧妙解決Excel公式迭代計(jì)算的問(wèn)題呢,下面小編就來(lái)和大家詳細(xì)講講吧
    2023-10-10
  • 深入學(xué)習(xí)JAVA GC日志的相關(guān)知識(shí)

    深入學(xué)習(xí)JAVA GC日志的相關(guān)知識(shí)

    JVM 在Java應(yīng)用程序優(yōu)化中是不可缺少的一大重項(xiàng),如何合理配置Java參數(shù),如何驗(yàn)證配置參數(shù)的有效性,從GC日志中可以獲得很重要的提示。下面小編就帶大家來(lái)一起學(xué)習(xí)一下吧
    2019-06-06
  • java獲取當(dāng)前時(shí)間和前一天日期(實(shí)現(xiàn)代碼)

    java獲取當(dāng)前時(shí)間和前一天日期(實(shí)現(xiàn)代碼)

    java獲取當(dāng)前時(shí)間和前一天日期的實(shí)現(xiàn)代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-10-10
  • Async的線程池使用選擇解析

    Async的線程池使用選擇解析

    這篇文章主要為大家介紹了Async的線程池使用選擇解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 如何利用SpringBoot搭建WebService服務(wù)接口

    如何利用SpringBoot搭建WebService服務(wù)接口

    之前項(xiàng)目經(jīng)理想要開(kāi)發(fā)一個(gè)webservice的協(xié)議,給我一個(gè)星期的時(shí)間,后面用springboot開(kāi)發(fā)了webservice,這篇文章主要給大家介紹了關(guān)于如何利用SpringBoot搭建WebService服務(wù)接口的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java用鄰接表存儲(chǔ)圖的示例代碼

    Java用鄰接表存儲(chǔ)圖的示例代碼

    鄰接表是圖的一種鏈?zhǔn)酱鎯?chǔ)方法,其數(shù)據(jù)結(jié)構(gòu)包括兩部分:節(jié)點(diǎn)和鄰接點(diǎn)。本文將用鄰接表實(shí)現(xiàn)存儲(chǔ)圖,感興趣的小伙伴可以了解一下
    2022-06-06
  • Spring如何使用@Indexed加快啟動(dòng)速度

    Spring如何使用@Indexed加快啟動(dòng)速度

    這篇文章主要介紹了Spring如何使用@Indexed加快啟動(dòng)速度,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • @TableName注解和@Table的區(qū)別及說(shuō)明

    @TableName注解和@Table的區(qū)別及說(shuō)明

    這篇文章主要介紹了@TableName注解和@Table的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論

屯昌县| 东丰县| 宣城市| 内江市| 福贡县| 怀安县| 清水县| 临猗县| 西畴县| 门源| 滦平县| 碌曲县| 噶尔县| 盐边县| 临泉县| 峨山| 北流市| 仙游县| 西乡县| 平南县| 清新县| 新干县| 临猗县| 习水县| 广德县| 安顺市| 高雄市| 白银市| 开封县| 巧家县| 任丘市| 德清县| 乐业县| 墨玉县| 邵武市| 遵义县| 渭源县| 都昌县| 潍坊市| 阳江市| 灵山县|