Spring IoC容器之容器擴展點

Spring IoC容器可以通過插入特殊的集成接口來實現(xiàn)拓展,而不需要繼承ApplicationContext的實現(xiàn)類。

1、BeanPostProcessor

org.springframework.beans.factory.config.BeanPostProcessor定義了回調(diào)方法,通過實現(xiàn)回調(diào)方法可以提供自己的實力話邏輯、依賴分析邏輯等。如果要在spring容器完成實例化、配置和初始化bean后,實例化一些自定義的邏輯,可以插入一個或多個BeanPostProcessor的實現(xiàn)。

我們可以配置多個BeanPostProcessor實例,也可以通過設(shè)置order屬性來控制這些BeanPostProcessor的執(zhí)行順序,還可以設(shè)置這個屬性僅作為BeanPostProcessor實現(xiàn)Ordered接口。如果編寫自己的BeanPostProcessor應(yīng)該考慮實現(xiàn)Ordered接口。

BeanPostProcessor定義

BeanPostProcessor接口定義了2個回調(diào)方法,當這樣的一個類注冊為容器的一個后置處理器時,由于每個bean實例都是由容器創(chuàng)建,這個后置處理器會在容器的初始化方法被調(diào)用前和任何bean實例化回調(diào)后從容器得到一個回調(diào)方法。后置處理器可以對bean采取任何措施,包括忽略回調(diào)。一個bean后置處理器,通常會檢查回調(diào)接口或使用代理包裝一個bean,部分AOP基礎(chǔ)設(shè)施類,為了提供包裝式的代理邏輯,倍實現(xiàn)為bean后置處理器。

ApplicationContext會自動檢測所有定義在配置元文件中,并實現(xiàn)了BeanPostProcessor接口的bean。ApplicationContext注冊這些bean作為后置處理器,使它們可以在bean創(chuàng)建完成后被調(diào)用,也可以像其他bean一樣被部署到容器中。

2、BeanFactoryPostProcessor

org.springframework.beans.factory.config.BeanFactoryPostProcessor接口與BeanPostProcessor類似,不同點是BeanFactoryPostProcessor操作bean的配置元數(shù)據(jù),即IoC容器允許BeanFactoryPostProcessor來讀取配置元數(shù)據(jù),并可以在容器實例化任何bean之前修改它。

BeanFactoryPostProcessor定義??

我們可以配置多個BeanFactoryPostProcessor實例,也可以通過設(shè)置order屬性來控制這些BeanFactoryPostProcessor的執(zhí)行順序,還可以設(shè)置這個屬性僅作為BeanFactoryPostProcessor實現(xiàn)Ordered接口。如果編寫自己的BeanFactoryPostProcessor應(yīng)該考慮實現(xiàn)Ordered接口。

3、FactoryBean

org.springframework.beans.factory.FactoryBean接口的對象是它們自己的工廠,它是IoC容器實例化邏輯的棵插拔點。如果初始化代碼比較復(fù)雜,則相對于大量的XML來說,最好是使用Java來表達。我們可以創(chuàng)建自己的FactoryBean,在類中編寫復(fù)雜的初始化代碼,再將自定義的FactoryBean插入到容器中。

FactoryBean定義

FactoryBean接口定義了三個方法:

\bullet getObject():返回工廠創(chuàng)建對象的實例,此實例是否被共享,取決于這個工廠返回的是單例還是原型實例。

\bullet getObjectType():返回由getObject()獲取的對象類型,或不知道類型時返回值為null。

\bullet isSingleton():若FactoryBean返回單例的實例,該方法返回true,否則返回false。

容器擴展示例:

\bullet PropertyPlaceholderConfigurer

PropertyPlaceholderConfigurer是BeanPostProcessor的一種實現(xiàn),它可以在標準的Properties格式的bean定義的分離文件中,用來具體化屬性值。這樣就允許應(yīng)用程序來自定義指定的環(huán)境屬性,如自定義數(shù)據(jù)庫連接信息,而無須修改容器的XML定義文件或其他文件。如下示例:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

? ? <property name="locations" values="classpath:jdbc.properties" />

</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"?destroy-method="close">

? ??<property name="driverClassName" values="${jdbc.driverClassName}" />

? ??<property name="url" values="${jdbc.url}" />

????<property name="username" values="${jdbc.username}" />

????<property name="password" values="${jdbc.password}" />

</bean>

?jdbc.properties文件定義:

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306

jdbc.username=root

jdbc.password=123456

dataSource的配置中使用了占位符來定義,從properties文件中獲取配置屬性。在運行時PropertyPlaceholderConfigurer會在bean定義的屬性中檢查占位符,然后匹配到properties中的鍵就會用其值替換${property-name}形式的占位符。spring2.5引入了context命名空間,可以使用專門的配置元素來配置屬性占位符。

<context:property-placeholder location="classpath:jdbc.properties" />

PropertyPlaceholderConfigurer不僅查看在Properties文件中指定的屬性,如果它不能在指定的屬性文件中找到屬性,也會檢查JavaSystem屬性,可以通過設(shè)置systemPropertiesMode屬性來定義行為:

1)never:從不檢查系統(tǒng)屬性。

2)fallback:如果沒有在指定的屬性文件中解析到屬性,就檢查系統(tǒng)屬性。

3)override:在檢查指定的屬性文件前,先去檢查系統(tǒng)屬性,允許系統(tǒng)屬性覆蓋其他任意的屬性資源。

\bullet PropertyOverrideConfigurer

PropertyOverrideConfigurer是BeanPostProcessor的另一種實現(xiàn),和PropertyPlaceholderConfigurer類似,它對于所有bean的屬性,原始定義可以有默認值或沒有值。如果一個Properties文件沒有特定bean的屬性配置項,就會使用默認的上下文定義。

由于bean定義是不知道被覆蓋的,因此從XML定義文件中并不能理解反映覆蓋配置文件被使用中。在多個PropertyOverrideConfigurer實例的情況下,為相同bean的屬性定義不同的值,只有最后一個有效,因其覆蓋機制導(dǎo)致的。

Properties屬性文件配置格式如下:

jdbc.driverClassName=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306

<context:property-override location="classpath:jdbc.properties" />


--參考文獻《Srping5開發(fā)大全》

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容