Spring提供了兩種后處理bean的擴展接口,分別為BeanPostProcessor和BeanFactoryPostProcessor,這兩者在使用上是有所區別的。
BeanPostProcessor:bean級別的處理,針對某個具體的bean進行處理
接口提供了兩個方法,分別是初始化前和初始化后執行方法,具體這個初始化方法指的是什么方法,類似我們在定義bean時,定義了init-method所指定的方法<bean id = "xxx" class = "xxx" init-method = "init()">
這兩個方法分別在init方法前后執行,需要注意一點,我們定義一個類實現了BeanPostProcessor,默認是會對整個Spring容器中所有的bean進行處理。
既然是默認全部處理,那么我們怎么確認我們需要處理的某個具體的bean呢?
可以看到方法中有兩個參數。類型分別為Object和String,第一個參數是每個bean的實例,第二個參數是每個bean的name或者id屬性的值。所以我們可以第二個參數,來確認我們將要處理的具體的bean。
這個的處理是發生在Spring容器的實例化和依賴注入之后。
BeanFactoryPostProcessor:BeanFactory級別的處理,是針對整個Bean的工廠進行處理
此接口只提供了一個方法,方法參數為ConfigurableListableBeanFactory,下面看看這個類里面定義了哪些方法
其中有個方法名為getBeanDefinition的方法,我們可以根據此方法,找到我們定義bean的BeanDefinition對象。然后我們可以對定義的屬性進行修改,以下是BeanDefinition中的方法
有沒有發現里面的方法名字類似我們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的處理功能更加強大。
以上個人理解,錯誤之處請指正!!!