2014-08-27 37 views
2

我有一個需求,需要從「外部」源動態加載Spring bean定義。此外部源可能是某種類型的文件,數據庫或Web服務。如何動態地將外部定義的bean定義添加到Spring上下文中?

我已經閱讀了關於BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor類,可以做這種類型的事情,但我遇到了一個很大的挑戰:

檢索從外部源豆definiton信息的對象被配置作爲一個bean本身(例如DatabaseBeanDefinitionProvider),所以它需要配置所有的依賴關係(例如DataSource)並且可以從上下文獲取數據。

我不確定在Spring應用程序上下文生命週期中的何處/何時執行此操作:實質上使用「現有bean來添加新bean」到上下文。

任何想法的專家?

+1

我想你需要動態創建和管理子上下文。幾乎沒有辦法將bean定義添加到已經初始化的上下文中(或者每次修改bean定義時都需要'刷新'上下文)。 – 2014-08-27 17:58:27

+0

你想動態添加的bean是否都實現了一組已知的接口? – 2014-08-27 18:12:45

+0

@PavelHoral - 這些動態bean的加載是一個應用程序初始化過程,所以它只需要刷新一次(我認爲),儘管我仍然有點不確定在初始化的位置執行此操作。 – WayneC 2014-08-27 19:20:31

回答

3

使用JdbcBeanDefinitionReader在Spring中實現了使用數據庫表來加載持久化bean定義的可能性。我提到這只是爲了確保你不會重新發明輪子;)。如果您只想依賴純文本中的一組屬性,也可以使用PropertiesBeanDefinitionReader。

這兩個類都有BeanDefinitionRegistry作爲依賴關係,這個存儲桶將在bean定義加載階段期間收集所有的bean定義。實現BeanDefinitionRegistryPostProcessor(BDRPP)接口以非常方便的方式提供了這個功能。基本上,如果你堅持DataSource綁定的方式,我會建議手動設置這些依賴關係,這意味着在自己的ApplicationContextInitializer實現中實例化BDRPP和依賴關係。在那裏,你可以調用applicationContext.addBeanFactoryPostProcessor(yourBdrpp)並在JdbcBeanDefinitionReader下加載DataSource所需的任何屬性。

如果您的所有依賴都獨立於任何自動裝配或屬性替換,那麼XML也將正常工作。你需要明確地定義它們,例如

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 
    <constructor-arg ref="dataSource"/> 
</bean> 

<bean class="net.bensteinert.MyBeanDefinitionRegistryPostProcessor"> 
    <constructor-arg ref="jdbcTemplate"/> 
</bean> 

唯一的問題是,你的數據源將擁有任何財產佔位符基礎設施用不上,這就是爲什麼我會傾向於編程解決方案的原因。

意思是一般情況下,不用擔心使用bean創建bean。他們只需要獨立。順便說一下,強大的Java Config引導也是一個BeanDefinitionRegistryPostProcessor。動態bean定義

更多細節也可以在這裏找到:How to create dynamic bean definitions in Spring

一個很好的介紹到Spring bean的生命週期可以在這裏找到:SpringONE 2013 Presentation by Mark Secrist

希望幫助, 這麼久。

相關問題