【二十】Spring IOC 總結之BeanFactory、ApplicationContext、BeanFactoryPostProcessor、BeanPostProcessor區別

一、BeanFactory和ApplicationContext的區別

1.BeanFacotry接口

負責生產和管理bean的一個工廠。

是Spring容器的頂層接口,提供了 IOC 容器應遵守的的最基本的接口

它有多種實現:如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等

但它是spring中比較原始的Factory無法支持spring的許多插件,如AOP功能、Web應用等。 

2.ApplicationContext接口

它由BeanFactory接口派生而來,因而提供BeanFactory所有的功能。

此外,因ApplicationContext還繼承了一些其他接口(具體看上圖),所以它還提供了以下的功能,而這些功能是BeanFacotry接口沒有的: 

1.利用MessageSource進行國際化 

由於ApplicationContext擴展了MessageResource接口,因而具有消息處理的能力(i18N)

2.資源訪問,如URL和文件  

ApplicationContext擴展了ResourceLoader(資源加載器)接口,從而可以用來加載多個Resource

3.強大的事件機制(Event)  

ApplicationContext的事件機制主要通過ApplicationEventPublisher來提供的

4.載入多個(有繼承關係)上下文 ,使得每一個上下文都專注於一個特定的層次,比如應用的web

其它區別  

  1.BeanFactroy採用的是延遲加載形式來注入Bean的,即只有在使用到某個Bean時(調用getBean()),纔對該Bean進行加載實例化,這樣,我們就不能發現一些存在的Spring的配置問題。而ApplicationContext則相反,它是在容器啓動時,一次性創建了所有的Bean。這樣,在容器啓動時,我們就可以發現Spring中存在的配置錯誤。 

  2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但兩者之間的區別是:BeanFactory需要手動註冊,而ApplicationContext則是自動註冊 

  3.BeanFactory通常以編程的方式被創建,ApplicationContext還能以聲明的方式創建,如使用ContextLoader。

二、FactoryBean

首先它是一個Bean,但又不只是一個Bean,而是一個能生產或者修飾對象生成的工廠Bean,它的實現與設計模式中的工廠模式和修飾器模式類似 .

spring中最爲典型的一個應用就是ProxyFactoryBean用來創建AOP的代理對象。

FactoryBean是一個接口,當在IOC容器中的Bean實現了FactoryBean後,通過getBean(String BeanName)獲取到的Bean對象並不是FactoryBean的實現類對象,而是這個實現類中的getObject()方法返回的對象

要想獲取FactoryBean的實現類,就要getBean(&BeanName),在BeanName之前加上&。

比如:

getBean('name')返回工廠中的實例,即是getObject()方法返回的對象

getBean('&name')返回FactoryBean本身的實例

三、BeanFactoryPostProcessor與BeanPostProcessor

1.BeanFactoryPostProcessor

BeanFactoryPostProcessor 爲spring在容器初始化時對外對外暴露的擴展點

Spring IoC容器允許BeanFactoryPostProcessor在容器加載註冊BeanDefinition完成之後讀取BeanDefinition(配置元數據),並可以修改它

ApplicationContext可以在其bean定義中自動檢測BeanFactoryPostProcessor bean,並在創建任何其他bean之前先創建BeanFactoryPostProcessor

BeanFactoryPostProcessor可以與bean定義交互並修改BeanDefinition,但絕不能與bean實例交互。如果在這裏就去觸發Bean的實例化會有兩個副作用:參考使用BeanFactoryPostProcessor——這種姿勢不要用

1.使用註解進行依賴注入失敗

2.可能會將ApplicationContext容器啓動過程暴露在多線程之下

如果需要bean實例交互,應考慮實現BeanPostProcessor。

實現BeanFactoryPostProcessor接口,可以允許我們的程序獲取到BeanFactory,從而修改BeanFactory,可以實現編程式的往Spring容器中添加Bean。

在Spring中ConfigurationClassPostProcessor這個BeanFactoryPostProcessor尤其重要。它會定位資源、加載解析BeanDefinition,註冊BeanDefinition

關於ConfigurationClassPostProcessor詳情請看前面的兩篇文章:

【十九】Spring IOC 總結之啓動時定位資源和BeanDefinition載入、解析、註冊(SpringBoot 掃啓動類所在包、starter、@Import)

【八】Spring源碼分析之掃描註冊Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法

這裏再推薦一篇我覺得講得很好的spring之BeanFactoryPostProcessor執行流程 

2.BeanPostProcessor

BeanPostProcessor是在getBean的時候,作用於bean的生命週期,比如實例化階段、初始化階段

詳情看以前的一篇:【十八】Spring IOC 總結之getBean主流程和各個擴展點總結

有幾個重要的BeanPostProcessor實現類需要關注一下

1.MergedBeanDefinitionPostProcess : 合併bean定義

2.AbstractAutoProxyCreator : 生成AOP代理的

3.ApplicationContextAwareProcessor :用來爲bean注入ApplicationContext等容器對象,會調用這幾種Aware的實現

EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware

4.CommonAnnotationBeanPostProcessor:支持@Resource註解的注入

5.RequiredAnnotationBeanPostProcessor:支持@Required註解的注入

6.AutowiredAnnotationBeanPostProcessor:支持@Autowired註解的注入

7.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext註解的注入
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章