BeanPostProcessor介面,(Bean的預處理器),可以讓你在bean完成實例化(instantiating)及組態設定(configuring)後,在初始化(initialization)的前後加入額外的邏輯設定(例如對bean的實例進行驗證修改bean的性質等等)。

你可以配置多個BeanPostProcessor的實作,須實作Ordered介面並實作getOrder()方法來決定執行的順序。

ApplicationContext會自動偵測Spring組態檔,只要bean的類別有實作BeanPostProcessor介面,就會被註冊為post-processor,之後容器內若有bean實例被建立,IoC容器就會去呼叫這些BeanPostProcessor的bean。
(看範例比較清楚)

BeanPostProcessor須實作兩個方法:

*postProcessBeforeInitialization - bean的初始方法在被容器呼叫前會執行此方法

*postProcessAfterInitialization - bean的初始方法在被容器呼叫後會執行此方法

 

範例(範例專案的建立參考這裡這裡)

總共需要建立四個檔案,

Bean的類別HelloWorld.java
實作BeanPostProcessor的類別InitHelloWorld.java
組態檔Beans.xml
執行程式的MainApp.java

 

專案目錄結構

 

Beans.xml...

...

注意第7行的bean,其class為InitHelloWord,該類別實作了BeanPostProcessor介面。因為ApplicationContext會自動偵測實作BeanPostProcessor的bean,所以沒有id或name也沒影響。

第9~12行設定"helloWorld"這個bean,由於BeanPostProcessor是在bean初始的前後被呼叫,所以必須設定bean的初始方法。

 

InitHelloWorld.java...

...

此類別實作了BeanPostProcessor介面(line 6),因此必須實作該介面中的兩個方法postProcessBeforeInitialization(line 5~11)及postProcessAfterInitialization(line 12~15)

此兩個方法須拋出BeanException例外。傳入的參數分別為bean物件及bean的名稱。

 

HelloWorld.java...

...

記得設定bean的初始及消滅方法

 

MainApp.java...

...

範例須呼叫registerShutdownHook()方法來藉此消滅bean(為了顯示執行的順序),所以context的型別為AbstractApplicationContext(line 9)

 

執行結果

 

 

-------------------

可以看到BeanPostProcessor的postProcessBeforeInitialization()方法會發生在bean初始化之前,postProcessAfterInitialization發生在bean初始化之後。

 

BeanPostProcessor的效果範圍是整個容器,所有的bean在實例化後皆會執行。

例如在多增加一個bean來測試看看

專案目錄結構

 

Beans.xml...

...

第13~16行新增一個"helloSpring"的bean,class為HelloSpring。 

 

HelloSpring.java...

...

和HelloWorld.java一樣,記得設定init()及destroy()方法。

 

MainApp.java...

...

新增第15~17行取得"helloSpring"bean的實例。

 

執行結果

可以看見執行開始Spring容器會將所有bean的實例都先實例化並初始化後,才會執行bean的方法,而registerShutdownHook()最後才會關閉context並消滅bean。

而BeanPostProcessor的效果會同時套用在容器內的bean。

 

關於多個BeanPostProcessor的執行順序設定請看下一篇。

 

參考於

tutorialspoint

http://docs.spring.io/spring/docs/4.0.x/

良葛格學習筆記

他山之石可以攻玉

DZone

 

文章標籤
創作者介紹

菲比傻大姐&肉豬

phoebelin0606 發表在 痞客邦 PIXNET 留言(0) 人氣()