2011-03-31 139 views
0

我需要在運行時機會Spring bean屬性值。目前我正在做這樣春天設置抽象豆屬性值

Object bean = context.getBean(beanName); 
BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean); 
wrapper.setPropertyValue(propertyName, newValue); 

但一些豆類配置爲抽象

<bean id="abstractFoo" abstract="true" class="com.Foo" /> 

<bean id="bar" class="com.Bar"> 
    <constructor-arg><bean parent="abstractFoo" /></constructor-arg> 
</bean> 

,並在這種情況下context.getBean("abstractFoo")拋出BeanIsAbstractException

這真是簡單的例子,但我希望你明白了。

任何想法如何更改抽象bean的屬性值(在這種情況下'abstractFoo')? 我們正在使用彈簧2.5.4

編輯

改變一個XML例子更加具體。由於安全原因,abstractFoo被聲明爲抽象。

+2

您需要謹慎從bean定義中區分出一個bean。例如''does * not *表示一個bean,只是一個bean定義。所以你不能以這個名字來請求一個bean,但是沒有這樣的bean。 – skaffman 2011-03-31 10:30:03

回答

2

Spring應用程序上下文包含bean定義,Spring實例化由這些定義定義的bean對象。

您當前的代碼將獲得一個從命名bean定義創建的對象,並更改其屬性。然而,bean永遠不會被實例化爲對象,它們僅以定義的形式存在,這些定義由具體bean的定義繼承。

所以,如果你想改變抽象bean的屬性,你需要改變它們的定義,這可以使用BeanFactoryPostProcessor來完成。但是,請注意,後置處理器在容器啓動期間應用,因此如果您希望它實際上是「運行時」,則此方法不適用。

+0

是的,它必須完成「運行時」此事的整體思路是,支持可以改變配置參數,而無需事後重新啓動應用程序。 – vrm 2011-03-31 10:46:29

+0

@vrm:我認爲在運行時更改配置比簡單修改bean屬性更復雜。通常,您的對象應該設計爲允許運行時配置更改。例如,您可以引入一個單獨的配置持有者對象,並使您的對象從中檢索配置屬性。 – axtavt 2011-03-31 11:44:18

+0

好的,但不幸的是,爲時已晚 – vrm 2011-03-31 13:08:45

0

聲明:這是未經測試;離開我的頭頂。不知道在啓動階段後它是否會工作。

您需要獲取ConfigurableListableBeanFactory的實例。你的appcontext可能是一個,所以你可以投它。

從那裏,獲取bean定義並更改屬性。

ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory)context; 
    BeanDefinition fooDefinition = clbf.getBeanDefinition("abstractFoo"); 
    MutablePropertyValues pv = fooDefinition.getPropertyValues(); 
    pv.add(propertyName, newValue); 

也許你需要重新註冊你的BeanDefinition與之後的ConfigurableListableBeanFactory。我不是100%肯定的;你必須測試一下。

請記住,如果它有效,它將只適用於在發生更改後實例化的豆。