Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

Spring提供了兩種後處理bean的擴展接口,分別為BeanPostProcessor和BeanFactoryPostProcessor,這兩者在使用上是有所區別的。

BeanPostProcessor:bean級別的處理,針對某個具體的bean進行處理

Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

接口提供了兩個方法,分別是初始化前和初始化後執行方法,具體這個初始化方法指的是什麼方法,類似我們在定義bean時,定義了init-method所指定的方法<bean>

這兩個方法分別在init方法前後執行,需要注意一點,我們定義一個類實現了BeanPostProcessor,默認是會對整個Spring容器中所有的bean進行處理。

既然是默認全部處理,那麼我們怎麼確認我們需要處理的某個具體的bean呢?

可以看到方法中有兩個參數。類型分別為Object和String,第一個參數是每個bean的實例,第二個參數是每個bean的name或者id屬性的值。所以我們可以第二個參數,來確認我們將要處理的具體的bean。

這個的處理是發生在Spring容器的實例化和依賴注入之後。


BeanFactoryPostProcessor:BeanFactory級別的處理,是針對整個Bean的工廠進行處理

Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

此接口只提供了一個方法,方法參數為ConfigurableListableBeanFactory,下面看看這個類裡面定義了哪些方法

Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

其中有個方法名為getBeanDefinition的方法,我們可以根據此方法,找到我們定義bean的BeanDefinition對象。然後我們可以對定義的屬性進行修改,以下是BeanDefinition中的方法

Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

Spring的BeanPostProcessor和BeanFactoryPostProcessor區別

有沒有發現裡面的方法名字類似我們bean標籤的屬性,setBeanClassName對應bean標籤中的class屬性,所以當我們拿到BeanDefinition對象時,我們可以手動修改bean標籤中所定義的屬性值。

具體這個BeanDefinition是個什麼對象,當我們在xml中定義了bean標籤時,Spring會把這些bean標籤解析成一個javabean,這個BeanDefinition就是bean標籤對應的javabean。

所以當我們調用BeanFactoryPostProcess方法時,這時候bean還沒有實例化,此時bean剛被解析成BeanDefinition對象。

Spring容器初始化bean大致過程 定義bean標籤>將bean標籤解析成BeanDefinition>調用構造方法實例化(IOC)>屬性值得依賴注入(DI)

所以BeanFactoryPostProcess方法的執行是發生在第二步之後,第三步之前。

總結:以上兩種都為Spring提供的後處理bean的接口,只是兩者執行的時機不一樣。前者為實例化之後,後者是實例化之前。功能上,後者對bean的處理功能更加強大。


分享到:


相關文章: