天天看點

Spring 源碼中的 BeanDefinition 是什麼

 一起來看看 BeanDefinition

Bean的定義主要由BeanDefinition來描述的。作為Spring中用于包裝Bean的資料結構,今天就來看看它的面紗下的真容吧。

首先就是BeanDefinition的類定義:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
複制代碼      

對,沒錯,這貨是個接口,而不是類,是不是有點莫名奇妙呢?我們都知道在JAVA中,接口是不能用來new出新的對象的,那麼在Spring中,到底将XML解析出來的Bean包裝成了什麼呢?(這個密等下揭開)

先來看看BeanDefinition一個繼承結構吧(均是與BeanDefinition有直接關聯的類或者接口)!

Spring 源碼中的 BeanDefinition 是什麼

從類圖中可以看出,BeanDefinition繼承了AttributeAccessor和BeanMetadataElement兩個接口;一個一個看。

AttributeAccessor

AttributeAccessor接口定義了最基本的對任意對象的中繼資料的修改或者擷取,主要方法有:

//将name定義的屬性設定為提供的value值。如果value的值為null,則該屬性為{@link #removeAttribute removed}。
//通常,使用者應該注意通過使用完全限定的名稱(可能使用類或包名稱作為字首)來防止與其他中繼資料屬性重疊。
void setAttribute(String name, Object value);
//擷取辨別為name的屬性的值。
Object getAttribute(String name);
//删除辨別為name的屬性,并傳回屬性值
Object removeAttribute(String name);
//如果名為name的屬性是否存在,存在傳回true,否則傳回false。
boolean hasAttribute(String name);
//傳回所有屬性的名稱。
String[] attributeNames();
複制代碼      

BeanMetadataElement

BeanMetadataElement接口提供了一個getResource()方法,用來傳輸一個可配置的源對象。

//傳回此中繼資料元素的配置源對象(可能為null)。
Object getSource();
複制代碼      

BeanDifinition源碼分析

一個BeanDefinition描述了一個bean的執行個體,包括屬性值,構造方法參數值和繼承自它的類的更多資訊。BeanDefinition僅僅是一個最簡單的接口,主要功能是允許BeanFactoryPostProcessor 例如PropertyPlaceHolderConfigure 能夠檢索并修改屬性值和别的bean的中繼資料(譯注)。

//标準單例作用域的作用域辨別符:“singleton”。
//對于擴充的bean工廠可能支援更多的作用域。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
複制代碼      
//标準原型作用域的範圍辨別符:“prototype”。
//對于擴充的bean工廠可能支援更多的作用域。
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
複制代碼      
//表示BeanDefinition是應用程式主要部分的角色提示。 通常對應于使用者定義的bean。
int ROLE_APPLICATION = 0;
複制代碼      

ROLE_SUPPORT =1實際上就是說,我這個Bean是使用者的,是從配置檔案中過來的。

//表示BeanDefinition是某些大型配置的支援部分的角色提示,通常是一個外部ComponentDefinition。
//當檢視某個特定的ComponentDefinition時,認為bean非常重要,
//以便在檢視應用程式的整體配置時能夠意識到這一點。
int ROLE_SUPPORT = 1;
複制代碼      

ROLE_INFRASTRUCTURE = 2就是我這Bean是Spring自己的,和你使用者沒有一毛錢關系。

//角色提示表明一個BeanDefinition是提供一個完全背景的角色,并且與最終使用者沒有關系。
//這個提示用于注冊完全是ComponentDefinition内部工作的一部分的bean
int ROLE_INFRASTRUCTURE = 2;
複制代碼      

上面是BeanDifinition的一些基本屬性資訊,一個就是辨別下目前Bean的作用域,另外就是辨別一下這個Bean是内部的還是外部的。下面來看這個接口為其子類都提供了哪些具體的行為方法:

1.目前Bean父類名稱get&set方法

//如果父類存在,設定這個bean定義的父定義的名稱。
void setParentName(String parentName);
//如果父類存在,則傳回目前Bean的父類的名稱
String getParentName();
複制代碼      

2.目前Bean的className get&set方法

//指定此bean定義的bean類名稱。
//類名稱可以在bean factory後期進行中修改,通常用它的解析變體替換原來的類名稱。
void setBeanClassName(String beanClassName);

//傳回此bean定義的目前bean類名稱。
//需要注意的是,這不一定是在運作時使用的實際類名,以防子類定義覆寫/繼承其父類的類名。
//此外,這可能隻是調用工廠方法的類,或者它 在調用方法的工廠bean引用的情況下甚至可能是空的。
//是以,不要認為這是在運作時定義的bean類型,而隻是将其用于在單獨的bean定義級别進行解析。
String getBeanClassName();
複制代碼      

3.Bean的作用域get&set方法

//覆寫此bean的目标範圍,指定一個新的範圍名稱。
void setScope(String scope);
//傳回此bean的目前目标作用域的名稱,如果沒有确定,傳回null
String getScope();
複制代碼      

4.懶加載的get&set方法

//設定這個bean是否應該被延遲初始化。如果{false},那麼這個bean将在啟動時由bean工廠執行個體化,
//這些工廠執行單例的立即初始化。
//懶加載 <bean lazy-init="true/false">
void setLazyInit(boolean lazyInit);
//傳回這個bean是否應該被延遲初始化,即不是在啟動時立即執行個體化。隻适用于單例bean。
boolean isLazyInit();
複制代碼      

5.依賴關系設定

//設定這個bean依賴被初始化的bean的名字。 bean工廠将保證這些bean首先被初始化。
//<bean depends-on="">
void setDependsOn(String... dependsOn);
//傳回這個bean依賴的bean名稱。
String[] getDependsOn();
複制代碼      

6.是否是自動轉配設定

//設定這個bean是否是獲得自動裝配到其他bean的候選人。
//需要注意是,此标志旨在僅影響基于類型的自動裝配。
//它不會影響按名稱的顯式引用,即使指定的bean沒有标記為autowire候選,也可以解決這個問題。
//是以,如果名稱比對,通過名稱的自動裝配将注入一個bean。
void setAutowireCandidate(boolean autowireCandidate);

//傳回這個bean是否是自動裝配到其他bean的候選者。就是是否在其他類中使用autowired來注入目前Bean的
//是否為被自動裝配 <bean autowire-candidate="true/false">
boolean isAutowireCandidate();
複制代碼      

7.主候選Bean

//是否為主候選bean    使用注解:@Primary
void setPrimary(boolean primary);
//傳回這個bean是否是主要的autowire候選者。
boolean isPrimary();
複制代碼      

8.定義建立該Bean對象的工廠類

//指定要使用的工廠bean(如果有的話)。 這是調用指定的工廠方法的bean的名稱。
void setFactoryBeanName(String factoryBeanName);
//傳回工廠bean的名字,如果有的話。
String getFactoryBeanName();
複制代碼      

9.建立該Bean對象的工廠方法

//如果有的話,指定工廠方法。
//這個方法先将通過構造函數參數被調用,或者如果參數,将調用該方法的無參數構造。
//方法将在指定的工廠bean(如果有的話)上被調用,或者作為本地bean類的靜态方法被調用。
void setFactoryMethodName(String factoryMethodName);
//如果存在,傳回工廠方法名
String getFactoryMethodName();
複制代碼      

10.傳回此bean的構造函數參數值。

//傳回此bean的構造函數參數值。
ConstructorArgumentValues getConstructorArgumentValues();
複制代碼      

11.擷取普通屬性集合

//擷取普通屬性集合
MutablePropertyValues getPropertyValues();
複制代碼      

12.目前Bean的基本特性

//是否是單例的
boolean isSingleton();
//是否是多例的
boolean isPrototype();
//是否是抽象類
boolean isAbstract();
複制代碼      

13.目前Bean的應用

//擷取這個bean的應用
int getRole();
複制代碼      
//傳回對bean定義的可讀描述。
String getDescription();
複制代碼      
//傳回該bean定義來自的資源的描述
String getResourceDescription();
複制代碼      
//傳回原始的BeanDefinition;如果沒有,則傳回null。允許檢索裝飾的bean定義(如果有的話)。
//注意,這個方法傳回直接的發起者。 疊代原始鍊,找到使用者定義的原始BeanDefinition。
BeanDefinition getOriginatingBeanDefinition();
複制代碼      
上一篇: jmeter斷言
下一篇: Vue.js - 核心