Spring源碼系列:BeanDefinition源碼解析

Bean的定義主要由BeanDefinition來描述的。做爲Spring中用於包裝Bean的數據結構,今天就來看看它的面紗下的真容吧。java

首先就是BeanDefinition的類定義:數據結構

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement 複製代碼

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

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

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

AttributeAccessor源碼分析

AttributeAccessor接口定義了最基本的對任意對象的元數據的修改或者獲取,主要方法有:spa

//將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();
複製代碼

BeanMetadataElementprototype

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

//返回此元數據元素的配置源對象(可能爲null)。
Object getSource();
複製代碼

BeanDifinition源碼分析

一個BeanDefinition描述了一個bean的實例,包括屬性值,構造方法參數值和繼承自它的類的更多信息。BeanDefinition僅僅是一個最簡單的接口,主要功能是容許BeanFactoryPostProcessor 例如PropertyPlaceHolderConfigure 可以檢索並修改屬性值和別的bean的元數據(譯註)。cdn

//標準單例做用域的做用域標識符:「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();
複製代碼

13.可讀描述

//返回對bean定義的可讀描述。
String getDescription();
複製代碼
//返回該bean定義來自的資源的描述
String getResourceDescription();
複製代碼
//返回原始的BeanDefinition;若是沒有,則返回null。容許檢索裝飾的bean定義(若是有的話)。
//注意,這個方法返回直接的發起者。 迭代原始鏈,找到用戶定義的原始BeanDefinition。
BeanDefinition getOriginatingBeanDefinition();
複製代碼

從上面的屬性和方法分析能夠看出,BeanDefinition對於一個Bean的描述作了較爲完整的一套約束。這爲後續的子類提供的最基本的職責和屬性。

歡迎關注glmapper工做室公衆號

相關文章
相關標籤/搜索