入門 16 - BeanFactoryPostProcessor接口 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
撰寫Bean定義檔通常使用XML來撰寫,XML階層式的組織爲各種元素與屬性設定來說相當的方便,然而XML文件在閱讀時總是要費點心力,尤其是在文件中充滿了許多定義內容時。
對於程序來說,有一些選項在設定好後通常就不會去變更,而有一些選項可能得隨時調整,這時候如果能提供一個更簡潔的設定檔,提供一些常用選項在其中隨時更改,這樣的程序在使用時會更有彈性。
我們可以實作org.springframework.beans.factory.config.BeanFactoryPostProcessor接口來提供這個功能:
BeanFactoryPostProcessor.java
public interface BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
從BeanFactoryPostProcessor接口的名稱上可以得知,實作此接口的Bean,可以在BeanFactory完成依賴注入後進行一些後繼處理動作,要作什麼動作取決於您,例如我們就可以在BeanFactory完成依賴注入後,根據我們提供的一個簡單屬性文件來設定一些經常變動的選 項。
不過這個功能,Spring已經爲我們提供了一個BeanFactoryPostProcessor的實作類別了: org.springframework.beans.factory.config.PropertyPlaceholderConfigurer。我 們來看一個Bean定義檔的實際例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="configBean" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>hello.properties</value>
</property>
</bean>
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
<property name="helloWord">
<value>${helloWord}</value>
</property>
....
</bean>
......
</beans>
假設在helloBean中有許多依賴注入的屬性,這些都是比較不常變動的屬性,而其中helloWord會經常變動,我們可以透過hello.properties來簡單的設定:
hello.properties
helloWord=Hello!Justin!
PropertyPlaceholderConfigurer會讀取location所設定的屬性文件,並將helloWord的值設定給${helloWord},從而完成依賴注入。
另一種情況是,XML定義檔中定義了一些低權限程序使用人員可以設定的選項,然而高權限的程序管理員可以透過屬性文件的設定,來推翻低權限程序使用人員的設 定,以完成高權限管理的統一性,Spring也提供了這麼一個BeanFactoryPostProcessor的實作類別: org.springframework.beans.factory.config.PropertyOverrideConfigurer。
來看看Bean定義檔如何設定:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="configBean" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="location">
<value>hello.properties</value>
</property>
</bean>
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
<property name="helloWord">
<value>Hello!caterpillar!</value>
</property>
....
</bean>
....
</beans>
在這個Bean定義檔中,雖然helloBean已經設定好helloWord屬性,然而高權限的管理者可以使用一個hello.properties來推翻這個設定:
hello.properties
helloBean.helloWord=Hello!Justin!
上面指定了helloBean的屬性helloWord爲Hello!Justin!,根據Bean定義檔與hello.properties的設定, 最後helloBean的helloWord會是Hello!Justin!而不是Hello!caterpillar!。