BeanFactory的總結
BeanFactory
BeanFactory是(shi)Spring容(rong)(rong)器中(zhong)的一(yi)個基(ji)本類也(ye)是(shi)很(hen)重要的一(yi)個類是(shi)Spring容(rong)(rong)器中(zhong)的一(yi)個基(ji)本類也(ye)是(shi)很(hen)重要的一(yi)個類,在BeanFactory中(zhong)可以創建和管理Spring容(rong)(rong)器中(zhong)的Bean,它對(dui)于Bean的創建有一(yi)個統一(yi)的流程。
Spring的本質是一個bean工廠(beanFactory)或者說bean容器,它按照我們的要求,生產我們需要的各種各樣的bean,提供給我們使用。
只是(shi)(shi)(shi)在(zai)生(sheng)產bean的過程中,需要解決(jue)bean之間的依(yi)賴(lai)(lai)問題,才(cai)引入了依(yi)賴(lai)(lai)注入(DI)這種技(ji)術。也就是(shi)(shi)(shi)說依(yi)賴(lai)(lai)注入是(shi)(shi)(shi)beanFactory生(sheng)產bean時為了解決(jue)bean之間的依(yi)賴(lai)(lai)的一種技(ji)術而已。
beanFactory會在bean的生命周期的各個階段中對bean進行各種管理,并且spring將這些階段通過各種接口暴露給我們,讓我們可以對bean進行各種處理,我們只要讓bean實現對應的接口,
那么spring就會在bean的(de)生命周期調用(yong)我(wo)們實現的(de)接口(kou)來處理(li)該(gai)bean.
在介紹BeanFactory前,我們先想一個問題。我們都知道BeanFactory主要的內容是幫我們生成Bean信息和管理Bean信息,那么我們在xml文件中
BeanDefinitionReader
從xml文件、類路徑下使用了@Component系列注解的類、或者從@Configuration注解的配置類,獲取BeanDefintiions,然后注冊到BeanFactory中。
我們通過(guo)BeanDefinitionReader從(cong)不同的(de)方式,獲取BeanDefintiions Bean的(de)元數據(ju)。
那么BeanDefintiions是(shi)什么?
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
setBeanClassName(original.getBeanClassName());
setScope(original.getScope());
setAbstract(original.isAbstract());
setFactoryBeanName(original.getFactoryBeanName());
setFactoryMethodName(original.getFactoryMethodName());
setRole(original.getRole());
setSource(original.getSource());
copyAttributesFrom(original);
。。。。。。省略
}
從上面的代碼我們大致的看出。BeanDefintiions其實就是對Bean的一些元數據定義,包括parenName 父類名稱 baenClassName:類名,scope bean的作用域。Abstract是否是抽象的等信息。
通過 BeanDefinitionReader獲取到BeanDefinition之后 。我們在通過BeanDefinitionRegistry將beanDefinition注冊到BeanFacory中。存儲在BeanFactory的一個conCurrentHashMap中。key為beanName,Value就是BeanDefinition元數據。
那么獲(huo)取(qu)Bean就從conCurrentHashMap中(zhong)通過BeanName獲(huo)取(qu)對(dui)應的Bean信息。
從上面的分析:我們可以看到Bean的加載解析過程如下圖所示:

接下來我們針對BeanDefinitionReader、BeanDefinitionRegistry、BeanFactory分(fen)別分(fen)析:
BeanDefinitionReader
- XmlBeanDefinitionReader:基于XML文件
讀取解析xml文件,通過Parser解析xml文件的標簽。
針對beans標簽,生成對應的BeanDefintions,然后注冊到BeanFactory中。
針對其他有特殊功能的標簽,如context:component-scan,context:anotation-config,還可以生成BeanFactoryPostProcessor,BeanPostProcessor接口實現類的bean等;除了可以生成BeanDefinitions之外,還可以實現其他功能。NamespaceHandler:XML標簽名稱空間處理器
被XmlBeanDefinitionReader使用,XmlBeanDefinitionReader在處理每個XML標簽名稱空間的時候,如applicationContext.xml的context:,mvc:,通過一個DefaultNamespaceHandlerResolver來獲取對應的NamespaceHandler實現類,然后通過這個NamespaceHandler實現類,進一步獲取該命名空間的內部標簽對應的BeanDefinitionParser實現類。
被(bei)XmlBeanDefinitionReader使用,專門(men)用于處(chu)理(li)xml文件的beans標簽的標簽處(chu)理(li)器。即XmlBeanDefinitionReader讀取xml文件,創建(jian)Document對(dui)象(xiang),然(ran)后交給BeanDefinitionDocumentReader處(chu)理(li)。BeanDefinitionDocumentReader解(jie)析Document對(dui)象(xiang)的Element節點,然(ran)后創建(jian)BeanDefinitions集合,通過XmlBeanDefinitionReader注冊到XmlBeanDefinitionReader所在的BeanFactory。
-
AnnotatedBeanDefinitionReader:注冊指定的類列表annotatedClasses
可以使用編程方法,顯示指定將哪些類需要注冊到BeanFactory。
主要是被AnnotationConfigApplicationContext使(shi)用(yong)(yong),即基于注(zhu)解配置(zhi)的ApplicationContext,這(zhe)是SpringBoot的默(mo)認ApplicationContext。典型使(shi)用(yong)(yong)為:先獲取所有(you)使(shi)用(yong)(yong)了@Configuration注(zhu)解的類,然后通過AnnotatedBeanDefinitionReader生成與(yu)這(zhe)些類對應的BeanDefinitions,并注(zhu)冊(ce)到BeanFactory。 -
ClassPathBeanDefinitionScanner:注冊指定的basePackages下面的類
掃描(miao)指(zhi)定(ding)類(lei)(lei)路(lu)徑(jing)(包)下(xia)面的(de)類(lei)(lei),檢測(ce)是否存在@Component注解及其(qi)子注解,從(cong)而生(sheng)成BeanDefinition,然(ran)后(hou)注冊到(dao)BeanFactory。沒(mei)有實現BeanDefinitionReader接口(kou),但基(ji)于(yu)相同(tong)(tong)的(de)設計思路(lu):BeanDefinitionReader。與AnnotatedBeanDefinitionReader一樣,都是獲取指(zhi)定(ding)類(lei)(lei),生(sheng)成該類(lei)(lei)的(de)BeanDefinition注冊到(dao)BeanFactory,而不是像xml文(wen)件一樣已經通過bean標(biao)簽顯(xian)示說明這個就是bean。也是主要(yao)是被AnnotationConfigApplicationContext使用。與其(qi)他兩種也是基(ji)于(yu)basePackages類(lei)(lei)路(lu)徑(jing)掃描(miao)的(de)方式不同(tong)(tong)之處(chu)為:context:component-scan標(biao)簽:基(ji)于(yu)XML的(de)ApplicationContext,實現類(lei)(lei)路(lu)徑(jing)掃描(miao),底層使用ComponentScanBeanDefinitionParser這個parser來處(chu)理(li)。@ComponentScan:對于(yu)處(chu)理(li)@Configuration配(pei)置類(lei)(lei)上(shang)面的(de)@ComponentScan注解,則是通過ComponentScanAnnotationParser來處(chu)理(li)的(de)。 -
ConfigurationClassBeanDefinitionReader:基于@Configuration注解的類配置
處理@Configuration注解的配置類,加在這些配置類上面的注解,即與@Configuration一起使用的注解,如@ComponentScan,@PropertySource,@Import,@Profile等。
ConfigurationClassBeanDefinitionReader主(zhu)要被ConfigurationClassPostProcessor調用(yong),ConfigurationClassPostProcessor為BeanFactoryPostProcessor
BeanDefinitionRegistry
注冊BeanDefinitions。提供registerBeanDefinition,removeBeanDefinition等方法,用來從BeanFactory注冊或移除BeanDefinition。
通常BeanFactory接口的實現類需要實現這個接口。
實現類(lei)(lei)(通常為BeanFactory接口實現類(lei)(lei))的對象實例,被DefinitionReader接口實現類(lei)(lei)引用(yong),DefinitionReader將BeanDefintion注(zhu)冊(ce)到(dao)該對象實例中。
除了上(shang)述的(de)BeanDefinitionRegisry還有一個負責單例Bean注冊的(de)接(jie)口:SingletonBeanRegistry
用于注(zhu)冊(ce)單例(li)Bean對(dui)象實(shi)(shi)例(li),實(shi)(shi)現類定(ding)義存(cun)儲Bean對(dui)象實(shi)(shi)例(li)的(de)map,BeanFactory的(de)類層次結構中需要實(shi)(shi)現這(zhe)個接口,來提供Bean對(dui)象的(de)注(zhu)冊(ce)和從(cong)Bean對(dui)象實(shi)(shi)例(li)的(de)map獲取bean對(dui)象。
BeanFactory
接口具體實現類
- DefaultListableBeanFactory
BeanFactory接口(kou)體系的(de)默認實(shi)現(xian)類,實(shi)現(xian)以(yi)上接口(kou)的(de)功(gong)能(neng),提供BeanDefinition的(de)存(cun)儲map,Bean對象對象的(de)存(cun)儲map。
其中Bean對象(xiang)實例的(de)存儲map,定義在FactoryBeanRegistrySupport,FactoryBeanRegistrySupport實現(xian)了SingletonBeanRegistry接(jie)口,而(er)DefaultListableBeanFactory的(de)基(ji)類AbstractBeanFactory,繼承于FactoryBeanRegistrySupport。
- StaticListableBeanFactory
用(yong)于存儲給(gei)定的bean對象(xiang)實(shi)(shi)例(li),不支持(chi)動態注(zhu)冊功能,是ListableBeanFactory接口的簡單(dan)實(shi)(shi)現。
beanFactoty后置處理器: BeanFactoryPostProcessor
benFactoryPostProCessor是BeanFactory的后(hou)置處理器:
在BeanFactory創建好,加載好其所(suo)包含(han)的所(suo)有(you)beanDefinitions,但(dan)是還沒有(you)實例化bean之(zhi)前,執行(xing),具體為調用postProcessBeanFactory方法。
-
加載更多的bean元數據
ConfigurationClassPostProcessor,用(yong)于從BeanFactory中檢測使(shi)(shi)(shi)用(yong)了@Configuration注(zhu)解的類(lei),對(dui)于這些(xie)類(lei)對(dui)應的BeanDefinitions集合,遍歷并(bing)依(yi)次(ci)交給ConfigurationClassParser,ConfigurationClassBeanDefinitionReader處(chu)理(li),分別是處(chu)理(li)與(yu)@Configuration同時使(shi)(shi)(shi)用(yong)的其他注(zhu)解和將類(lei)內部(bu)的使(shi)(shi)(shi)用(yong)@Bean注(zhu)解的方法,生(sheng)成BeanDefinition,注(zhu)冊到BeanFactory。 -
對bean元數據進行加工處理
BeanDefinition屬(shu)性填充、修改:在(zai)postProcessBeanFactory方法(fa)中(zhong),可以對(dui)beanFactory所包(bao)含的(de)beanDefinitions的(de)propertyValues和構造函數參數值(zhi)進(jin)行(xing)(xing)修改,如使用PropertyPlaceHolderConfigurer來對(dui)BeanDefinition的(de)propertyValues的(de)占(zhan)位符進(jin)行(xing)(xing)填充、賦值(zhi)。或者(zhe)(zhe)使用PropertyResourceConfigurer獲取(qu)config文件(jian)中(zhong)屬(shu)性,對(dui)BeanDefinitions的(de)相(xiang)關屬(shu)性進(jin)行(xing)(xing)賦值(zhi)或者(zhe)(zhe)值(zhi)覆蓋。
bean對象后置處(chu)理器:BeanPostProcessor
Bean后置處(chu)理器:負責對已創建好的bean對象進(jin)行加工(gong)處(chu)理。
主要是可以(yi)對(dui)新創建(jian)的bean實(shi)例進(jin)行(xing)修改,提供了一個(ge)類似(si)于(yu)hook機(ji)制,對(dui)創建(jian)好的bean對(dui)象(xiang)實(shi)例進(jin)行(xing)修改。
核心方法
postProcessBeforeInitialization:在(zai)創建好(hao)bean實例,但是在(zai)任何初始化(hua)回調執行之前(qian),如InitializingBean的afterPropertiesSet,先執行該方法(fa)。
postProcessAfterInitialization:在創建好bean實例,并且所有的(de)初始(shi)化回調都(dou)執行完了,如(ru)InitializingBean的(de)afterPropertiesSet,再執行該方法。