您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關BeanDefinition的原理是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
首先我提出一個問題:一個java對象和一個Spring Bean有什么區別?
這是一個經典的面試題,什么是java Object
?萬物皆對象,在Java內部所有的類,經過創建之后都可以稱之為一個對象,SpringBean也是一個java Object
, 但是Spring Bean是脫離
于JAVA Object的,為什么這么說呢?因為一個class要想變成對象只需要new
一下,就能夠稱之為一個對象,但是一個類要想變成一個Spring Bean就需要經過一系列的生命周期,什么生命周期呢?后面會說到!
至少從上面的可以知道,Spring Bean是一個特殊的Java Object, 那么他肯定有和JAVA Object有不一樣的地方!
Java中 Class對象可以描述一個JAVA Object,但是因為Spring Bean是一個特殊的JAVA Object,所以Class對象不能夠完整的描述一個Spring Bean,所以Spring官方單獨開發了一個叫做BeanDefinition
的類,來描述一個SpringBean
!
BeanDefinition
里面描述了很多的東西,大致如下:
它里面存放了Spring創建bean的過程中所需要的一切原料!
通過上面的介紹,那么你對
BeanDefinition
有了一大概的認識,那么我們在了解整個Spring的聲明周期的時候,需要了解兩個概念BeanFactoryPostProcessor
、BeanPostProcessor
,當然這里只是普及一下概念,是為了能夠讓讀者更加深入的去理解Spring的聲明周期!
我們現在通過上面的了解知道了一件事,就是Spring在創建對象之前會把class轉換成一個BeanDefinition
, 此時Spring為我們提供了一個擴展點,他可以在讀取完全部的class轉換為 BeanDefinition
之后,回調所有實現了BeanFactoryPostProcessor
接口的實現類,并傳入工廠對象,使得使用者能夠對工廠對象內部的屬性進行修改,例如:對BeanDefinition
內的信息進行修改,以達到操縱最終實例化bean的目的!
說白了,他會在掃描完項目將Class轉換為BeanDefinition
之后在進行實例化之前進行接口的回調!
這個類和上面那個類十分的相似,他有兩個方法,兩個方法的調用時機也不相同,他會在實例化之后,調用初始化方法之前進行第一次方法回調(postProcessBeforeInitialization),在執行完初始化方法之后又會進行一次回調(postProcessAfterInitialization),每次回調該類都會將當前創建好的bean傳遞到方法內部,從而讓開發者能夠自定義的修改當前bean的一些定義!
那么此時,我們了解了BeanDefinition
、BeanPostProcessor
、BeanFactoryPostProcessor
這三個概念之后,我們可以嘗試著學習一下Spring的生命周期,學習Spring聲明周期對掌握Spring源碼具有舉足輕重的地位!只有了解Spring的聲明周期,才能夠對后續Spring系列的技術進行一個詳盡的源碼掌握!
整個Spring的生命周期,以文字描述大概分為以下幾個階段:
BeanFactoryPostProcessor
掃描項目將所有的
@Bean、@Component....
或者
xml配置
等符合Spring讀取對應的類解析成
BeanDefinition
,存儲在容器里面!BeanFactoryPostProcessor
BeanPostProcessor
到容器內部!BeanPostProcessors.postProcessBeforeInitialization
方法BeanPostProcessors.postProcessAfterInitialization
方法盡管我們可以通過實現BeanDefinition
接口創建一個自定義的BeanDefinition
,但是你是否發現,自己實現這個接口,想要創建一個BeanDefinition
極其復雜里面幾十個屬性都需要你自己去設置;
Spring官方為了簡化這一步驟,提供了一個抽象AbstractBeanDefinition
,這個抽象類內部默認實現了BeanDefinition
的絕大部分方法,對一些屬性進行了默認值的賦值,極大地簡化了用戶自己實現一個BeanDefinition
的難度!
他是AbstractBeanDefinition
的子類,我們通過注解配置的bean以及我們的配置類(除@Bean
)外的BeanDefiniton
類型都是GenericBeanDefinition
類型的!
Spring在啟動時會實例化幾個初始化的BeanDefinition
,這幾個BeanDefinition
的類型都為RootBeanDefinition
,這個包括后續Spring的BeanDefinition會進行一個合并(這都是后話)都是RootBeanDefinition
類型的!
我們通過 @Bean
創建的BeanDefinition
也是RootBeanDefinition類型,當然是屬于他的子類(后面會介紹)的!
這個接口直接繼承了BeanDefinition
,他在原來的基礎上擴展了兩個方法:
這兩個方法是專門對注解讀取的方法!所有注解標識的bean都是這個類型的bean!
第一種情況是配置類也就是標注了@Configuration
注解的類會被解析成 AnnotatedGenericBeanDefinition
第二種情況是通過@Import
導入的類會被解析成AnnotatedGenericBeanDefinition
通過@Bean
注解導入的類會被解析為ConfigurationClassBeanDefinition
通過@Service、@Compent
等方式創建的bean 會以ScannedGenericBeanDefinition
的形式存在!
上述就是小編為大家分享的BeanDefinition的原理是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。