Spring BeanDefinition使用介紹
1. 前言
Spring最重要的一個概念當(dāng)屬Bean了,我們寫的Controller、Service、Dao凡是加了對應(yīng)注解交給Spring管理的,都是Spring容器中的一個Bean。把我們自己寫的類變成一個Bean交給Spring管理有很多的好處,比如我們不用自己去new對象了,Spring會幫我們在適當(dāng)?shù)臅r候去實例化對象;再比如Spring還會維護(hù)Bean的依賴關(guān)系,自動注入依賴的對象;再比如Spring還可以基于Bean生成代理對象,來對原生的Bean進(jìn)行功能上的增強等等。
在Spring源碼中,有一個重要的接口BeanDefinition,它用來表示Bean的定義。比如Bean的名稱、所屬的Class、是否需要延遲實例化,是單例還是原型?等等信息。不管你是通過xml來配置,還是JavaConfig的方式,還是基于注解的方式,在Spring看來它們都是一個BeanDefinition。
2. BeanDefinition
BeanDefinition是一個接口,本身的類圖還是比較簡單的,繼承了AttributeAccessor和BeanMetadataElement接口。

2.1 AttributeAccessor
AttributeAccessor接口代表一個屬性訪問器,它的作用是可以給Bean附加一些自定義的屬性,并提供訪問方法。
例如:originalTargetClass屬性代表AOP被代理的原始Class對象;preserveTargetClass屬性代表是否基于類進(jìn)行代理。
AttributeAccessorSupport是其中一個實現(xiàn)類,它底層通過LinkedHashMap來存儲這些附加屬性。
public interface AttributeAccessor {
void setAttribute(String name, @Nullable Object value);
Object getAttribute(String name);
Object removeAttribute(String name);
boolean hasAttribute(String name);
String[] attributeNames();
}2.2 BeanMetadataElement
BeanMetadataElement接口我也不是很清楚具體作用是啥,網(wǎng)上對它的介紹也比較少。
public interface BeanMetadataElement {
/**
* 對于常規(guī)Bean,可以獲得Bean對應(yīng)的Resource
*/
@Nullable
Object getSource();
}
經(jīng)過實驗發(fā)現(xiàn),對于常規(guī)的Bean來說,可以通過getSource()方法獲取Bean對應(yīng)的資源。例如:現(xiàn)在有一個BeanDefinition它的BeanClass來自ClassPath下的包,getSource()方法可以獲取到這個Class文件對應(yīng)的FileSystemResource資源。
2.3 BeanDefinition
終于看到主角了,BeanDefinition還是一個接口,它提供了一系列方法來讀寫B(tài)ean的一些屬性定義,方法名基本都能見名知意,注釋里已經(jīng)把方法的作用寫上了。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/**
* 父Bean的name 對應(yīng)XML里的 <bean parent=""> 配置
*/
void setParentName(@Nullable String parentName);
String getParentName();
/**
* BeanClassName 對應(yīng)XML里的 <bean class=""> 配置
*/
void setBeanClassName(@Nullable String beanClassName);
String getBeanClassName();
/**
* Bean的作用域 單例/原型
*/
void setScope(@Nullable String scope);
String getScope();
/**
* 是否延遲加載
* 默認(rèn)為fale,容器啟動時自動實例化單例Bean
* 設(shè)置為true,則在getBean時再實例化
*/
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
/**
* 依賴的其它Bean
* BeanFactory保證先實例化依賴的Bean
*/
void setDependsOn(@Nullable String... dependsOn);
String[] getDependsOn();
/**
* 當(dāng)前Bean是否作為其它Bean依賴注入時的候選Bean,默認(rèn)為true
* Spring根據(jù)Type注入時,如果存在多個實現(xiàn)類,會拋出異常
* 通過將autowireCandidate設(shè)置為false,該Bean將不再是依賴注入時的候選Bean
* 根據(jù)name注入時,不受影響
*/
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
/**
* 依賴注入 存在多個候選Bean時,優(yōu)先注入primary=true的
*/
void setPrimary(boolean primary);
boolean isPrimary();
void setFactoryBeanName(@Nullable String factoryBeanName);
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
String getFactoryMethodName();
/**
* Bean的構(gòu)造函數(shù)參數(shù)值
*/
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* 獲取Bean實例的屬性值
*/
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
/**
* Bean初始化的方法名
*/
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
/**
* Bean銷毀的方法名
*/
void setDestroyMethodName(@Nullable String destroyMethodName);
String getDestroyMethodName();
void setRole(int role);
int getRole();
/**
* Bean的描述
*/
void setDescription(@Nullable String description);
String getDescription();
/**
* 是否是單例的
*/
boolean isSingleton();
/**
* 是否是原型的
*/
boolean isPrototype();
/**
* 是否是抽象Bean,如果是將不會實例化
*/
boolean isAbstract();
@Nullable
String getResourceDescription();
/**
* 獲取原始的BeanDefinition
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
2.4 AbstractBeanDefinition
AbstractBeanDefinition是一個抽象類,實現(xiàn)了絕大多數(shù)BeanDefinition的功能,源碼也很簡單,通過大量屬性來記錄BeanDefinition對應(yīng)方法設(shè)置的屬性值,代碼就不貼了。
2.5 GenericBeanDefinition
GenericBeanDefinition是一個類,它是BeanDefinition的標(biāo)準(zhǔn)實現(xiàn),繼承自AbstractBeanDefinition。剛剛已經(jīng)說過了,由于AbstractBeanDefinition已經(jīng)實現(xiàn)了絕大多數(shù)方法了,所以GenericBeanDefinition的代碼也極其簡單,只實現(xiàn)了一個讀寫parentName的方法。
2.6 AnnotatedGenericBeanDefinition
顧名思義,AnnotatedGenericBeanDefinition是一個基于注解的BeanDefinition標(biāo)準(zhǔn)實現(xiàn),它繼承自GenericBeanDefinition,已經(jīng)獲得了BeanDefinition完整的能力了。只不過,由于是基于注解的標(biāo)準(zhǔn)實現(xiàn),所以它還實現(xiàn)了AnnotatedBeanDefinition接口,以此來獲得獲取注解元數(shù)據(jù)的能力。
public interface AnnotatedBeanDefinition extends BeanDefinition {
// 獲取注解元數(shù)據(jù)
AnnotationMetadata getMetadata();
// 獲取工廠方法元數(shù)據(jù)的能力
MethodMetadata getFactoryMethodMetadata();
}
AnnotatedGenericBeanDefinition的代碼也同樣極其簡單,只是提供了兩個屬性metadata和factoryMethodMetadata來記錄注解元數(shù)據(jù)和工廠方法元數(shù)據(jù)而已。
2.7 其它實現(xiàn)
本文著重分析了AnnotatedGenericBeanDefinition這一條分支,實際上在Spring中BeanDefinition還有很多實現(xiàn)類,例如:
- RootBeanDefinition:ChildBeanDefinition:基于父Bean的子BeanDefinition。
- ConfigurationClassBeanDefinition:加了@Bean注解的BeanDefinition。
- ScannedGenericBeanDefinition:加了@Component及其派生注解的BeanDefinition。
到此這篇關(guān)于Spring BeanDefinition使用介紹的文章就介紹到這了,更多相關(guān)Spring BeanDefinition內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringIOC?BeanDefinition的加載流程詳解
- Spring注解驅(qū)動之BeanDefinitionRegistryPostProcessor原理解析
- 如何利用Spring把元素解析成BeanDefinition對象
- Spring超詳細(xì)講解創(chuàng)建BeanDefinition流程
- BeanDefinitionRegistryPostProcessor如何動態(tài)注冊Bean到Spring
- Spring Bean生命周期之BeanDefinition的合并過程詳解
- springboot自動掃描添加的BeanDefinition源碼實例詳解
- Spring應(yīng)用拋出NoUniqueBeanDefinitionException異常的解決方案
相關(guān)文章
java使用Logback配置輸出日志內(nèi)容到文件示例代碼
這篇文章主要介紹了java?Logback輸出日志內(nèi)容到文件,要將logger.info的信息輸出到文件,您可以使用Logback配置,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
詳解JAVA抓取網(wǎng)頁的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片
這篇文章主要介紹了詳解JAVA抓取網(wǎng)頁的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片,非常具有實用價值,需要的朋友可以參考下。2016-12-12
利用Java代碼實現(xiàn)區(qū)塊鏈技術(shù)
這篇文章主要介紹了利用Java代碼實現(xiàn)區(qū)塊鏈技術(shù),區(qū)塊鏈的應(yīng)用范圍幾乎無窮無盡,關(guān)于區(qū)塊鏈?zhǔn)侨绾芜\作的,下文來看看具體的內(nèi)容介紹吧,需要的朋友可以參考一下2022-04-04
Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn)
這篇文章主要介紹了Java 最優(yōu)二叉樹的哈夫曼算法的簡單實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10

