BeanFactory的總結
BeanFactory
BeanFactory是Spring容器中的一個基本類也是很重要的一個類是Spring容器中的一個基本類也是很重要的一個類,在BeanFactory中可以創建和管理Spring容器中的Bean,它對于Bean的創建有一個統一的流程。
Spring的本質是一個bean工廠(beanFactory)或者說bean容器,它按照我們的要求,生產我們需要的各種各樣的bean,提供給我們使用。
只是在生產bean的過程中,需要解決bean之間的依賴問題,才引入了依賴注入(DI)這種技術。也就是說依賴注入是beanFactory生產bean時為了解決bean之間的依賴的一種技術而已。
beanFactory會在bean的生命周期的各個階段中對bean進行各種管理,并且spring將這些階段通過各種接口暴露給我們,讓我們可以對bean進行各種處理,我們只要讓bean實現對應的接口,
那么spring就會在bean的生命周期調用我們實現的接口來處理該bean.
在介紹BeanFactory前,我們先想一個問題。我們都知道BeanFactory主要的內容是幫我們生成Bean信息和管理Bean信息,那么我們在xml文件中
BeanDefinitionReader
從xml文件、類路徑下使用了@Component系列注解的類、或者從@Configuration注解的配置類,獲取BeanDefintiions,然后注冊到BeanFactory中。
我們通過BeanDefinitionReader從不同的方式,獲取BeanDefintiions Bean的元數據。
那么BeanDefintiions是什么?
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元數據。
那么獲取Bean就從conCurrentHashMap中通過BeanName獲取對應的Bean信息。
從上面的分析:我們可以看到Bean的加載解析過程如下圖所示:

接下來我們針對BeanDefinitionReader、BeanDefinitionRegistry、BeanFactory分別分析:
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實現類。
被XmlBeanDefinitionReader使用,專門用于處理xml文件的beans標簽的標簽處理器。即XmlBeanDefinitionReader讀取xml文件,創建Document對象,然后交給BeanDefinitionDocumentReader處理。BeanDefinitionDocumentReader解析Document對象的Element節點,然后創建BeanDefinitions集合,通過XmlBeanDefinitionReader注冊到XmlBeanDefinitionReader所在的BeanFactory。
-
AnnotatedBeanDefinitionReader:注冊指定的類列表annotatedClasses
可以使用編程方法,顯示指定將哪些類需要注冊到BeanFactory。
主要是被AnnotationConfigApplicationContext使用,即基于注解配置的ApplicationContext,這是SpringBoot的默認ApplicationContext。典型使用為:先獲取所有使用了@Configuration注解的類,然后通過AnnotatedBeanDefinitionReader生成與這些類對應的BeanDefinitions,并注冊到BeanFactory。 -
ClassPathBeanDefinitionScanner:注冊指定的basePackages下面的類
掃描指定類路徑(包)下面的類,檢測是否存在@Component注解及其子注解,從而生成BeanDefinition,然后注冊到BeanFactory。沒有實現BeanDefinitionReader接口,但基于相同的設計思路:BeanDefinitionReader。與AnnotatedBeanDefinitionReader一樣,都是獲取指定類,生成該類的BeanDefinition注冊到BeanFactory,而不是像xml文件一樣已經通過bean標簽顯示說明這個就是bean。也是主要是被AnnotationConfigApplicationContext使用。與其他兩種也是基于basePackages類路徑掃描的方式不同之處為:context:component-scan標簽:基于XML的ApplicationContext,實現類路徑掃描,底層使用ComponentScanBeanDefinitionParser這個parser來處理。@ComponentScan:對于處理@Configuration配置類上面的@ComponentScan注解,則是通過ComponentScanAnnotationParser來處理的。 -
ConfigurationClassBeanDefinitionReader:基于@Configuration注解的類配置
處理@Configuration注解的配置類,加在這些配置類上面的注解,即與@Configuration一起使用的注解,如@ComponentScan,@PropertySource,@Import,@Profile等。
ConfigurationClassBeanDefinitionReader主要被ConfigurationClassPostProcessor調用,ConfigurationClassPostProcessor為BeanFactoryPostProcessor
BeanDefinitionRegistry
注冊BeanDefinitions。提供registerBeanDefinition,removeBeanDefinition等方法,用來從BeanFactory注冊或移除BeanDefinition。
通常BeanFactory接口的實現類需要實現這個接口。
實現類(通常為BeanFactory接口實現類)的對象實例,被DefinitionReader接口實現類引用,DefinitionReader將BeanDefintion注冊到該對象實例中。
除了上述的BeanDefinitionRegisry還有一個負責單例Bean注冊的接口:SingletonBeanRegistry
用于注冊單例Bean對象實例,實現類定義存儲Bean對象實例的map,BeanFactory的類層次結構中需要實現這個接口,來提供Bean對象的注冊和從Bean對象實例的map獲取bean對象。
BeanFactory
接口具體實現類
- DefaultListableBeanFactory
BeanFactory接口體系的默認實現類,實現以上接口的功能,提供BeanDefinition的存儲map,Bean對象對象的存儲map。
其中Bean對象實例的存儲map,定義在FactoryBeanRegistrySupport,FactoryBeanRegistrySupport實現了SingletonBeanRegistry接口,而DefaultListableBeanFactory的基類AbstractBeanFactory,繼承于FactoryBeanRegistrySupport。
- StaticListableBeanFactory
用于存儲給定的bean對象實例,不支持動態注冊功能,是ListableBeanFactory接口的簡單實現。
beanFactoty后置處理器: BeanFactoryPostProcessor
benFactoryPostProCessor是BeanFactory的后置處理器:
在BeanFactory創建好,加載好其所包含的所有beanDefinitions,但是還沒有實例化bean之前,執行,具體為調用postProcessBeanFactory方法。
-
加載更多的bean元數據
ConfigurationClassPostProcessor,用于從BeanFactory中檢測使用了@Configuration注解的類,對于這些類對應的BeanDefinitions集合,遍歷并依次交給ConfigurationClassParser,ConfigurationClassBeanDefinitionReader處理,分別是處理與@Configuration同時使用的其他注解和將類內部的使用@Bean注解的方法,生成BeanDefinition,注冊到BeanFactory。 -
對bean元數據進行加工處理
BeanDefinition屬性填充、修改:在postProcessBeanFactory方法中,可以對beanFactory所包含的beanDefinitions的propertyValues和構造函數參數值進行修改,如使用PropertyPlaceHolderConfigurer來對BeanDefinition的propertyValues的占位符進行填充、賦值。或者使用PropertyResourceConfigurer獲取config文件中屬性,對BeanDefinitions的相關屬性進行賦值或者值覆蓋。
bean對象后置處理器:BeanPostProcessor
Bean后置處理器:負責對已創建好的bean對象進行加工處理。
主要是可以對新創建的bean實例進行修改,提供了一個類似于hook機制,對創建好的bean對象實例進行修改。
核心方法
postProcessBeforeInitialization:在創建好bean實例,但是在任何初始化回調執行之前,如InitializingBean的afterPropertiesSet,先執行該方法。
postProcessAfterInitialization:在創建好bean實例,并且所有的初始化回調都執行完了,如InitializingBean的afterPropertiesSet,再執行該方法。
浙公網安備 33010602011771號