2010-11-11 72 views
2

我在例如定義的bean中有一個bean(id =「myBean」)。 core.xml。 myBean不是抽象的,它在此文件中的定義不能被修改。在另一個XML文件中定義的bean上設置一個屬性

不過,我需要設置一個新的屬性(myProperty的)不知何故,在一個單獨的XML文件(overrides.xml)core.xml是在一個特定的客戶端站點加載後加載。

如果我重新定義了bean的第二次了,這次給myProperty的一個值,春季(2.5)拒絕爲重複bean定義(不夠公平)。

我想知道如何在不破壞/更改原始bean定義的情況下在overrides.xml中設置此屬性。

猜測AOP和可能的自動代理是某種方式來做到這一點,但到目前爲止我無法找到答案。如果任何人都可以提供幫助,將會很感激

順便說一下,我的問題與How do I override a Spring bean definition yet still reference the overridden bean?完全一樣,但我還沒有弄清楚作者是如何修復它的(並且也有一個建議,這是不可能的,這會讓我很傷心,如果真的...!)

感謝

+0

您能否提供一些示例XML來更好地說明問題? – 2010-11-11 13:10:53

回答

2

可以使用BeanPostProcessor基礎的解決方案:

public class AdditionalPropertiesBeanPostProcessor 
implements BeanPostProcessor{ 

    private Map<String, Map<String, Object>> propertiesMap; 

    public void setPropertiesMap(
     final Map<String, Map<String, Object>> propertiesMap){ 
     this.propertiesMap = propertiesMap; 
    } 

    @Override 
    public Object postProcessBeforeInitialization(final Object bean, 
     final String beanName) throws BeansException{ 
     final Map<String, Object> props = propertiesMap.get(beanName); 
     if(props != null){ 
      final BeanWrapper bw = new BeanWrapperImpl(bean); 
      for(final Entry<String, Object> entry : props.entrySet()){ 
       bw.setPropertyValue(entry.getKey(), entry.getValue()); 
      } 
     } 
     return bean; 
    } 

    @Override 
    public Object postProcessAfterInitialization(final Object bean, 
     final String beanName) throws BeansException{ 
     return bean; 
    } 

} 

這是bean定義:

<bean class="foo.bar.AdditionalPropertiesBeanPostProcessor"> 
    <property name="propertiesMap"> 
     <map> 
      <!-- Reference the bean by name --> 
      <entry key="yourBeanName"> 
       <map> 
        <!-- Supports Strings (and other standard types), --> 
        <entry key="propertyOne" value="abc" /> 
        <!-- Bean references, --> 
        <entry key="service" value-ref="fooService" /> 
        <!-- and inner beans --> 
        <entry key="someOtherProperty"> 
         <bean class="foo.bar.SomeBean" /> 
        </entry> 

       </map> 
      </entry> 
     </map> 
    </property> 
</bean> 

現在,所有這些Bean的bean的名字可以在地圖中找到將額外填充您指定的屬性。

我不知道這種方法是否可以在各種層次上下文中工作,但是如果定義了處理器的上下文導入了其他上下文,我證實它可以工作。

此解決方案不適用於其他問題,因爲這是關於構造函數注入。該解決方案僅適用於標準的java bean屬性。

+0

嘿,這真棒。我剛剛嘗試過,效果很好。我特別喜歡它,因爲我將來也可以將它用於其他豆類。謝謝,這當然回答了我的問題! – Richard 2010-11-11 14:34:54

+0

哦,我必須糾正的一個(非常小)的變化:它說value =「yourBeanName」,這應該是key =「yourBeanName」 – Richard 2010-11-11 14:35:48

+0

@Richard修復,謝謝 – 2010-11-11 14:40:50

0

如果我正確地讀出了答案,你需要的BeanNameAutoProxyCreator。您的Spring版本的JavaDoc是here

+1

?他想設置屬性,而不是添加代理。 – 2010-11-11 13:29:56

2

兩個相互矛盾的聲明:

  1. 豆不能修改
  2. 我必須修改豆。

這是哪一個?

您可以創建一個表達不可修改的bean的界面,使用可修改的版本擴展它,並使用組合。

+0

對不起,我的意思是原始的bean定義(在core.xml中)不能修改。但是,我可以在第二個XML文件中做我想做的事情,而這正是我需要設置'myProperty'的地方。我一直在嘗試使用BeanNameAutoProxyCreator,但是從我所知道的情況來看,您不能使用Spring AOP修改字段(至少在版本2.5中)。很高興能夠糾正。 – Richard 2010-11-11 12:35:57

+0

* for * Bean無法修改。我必須修改這個bean。這是什麼?* :-) – 2010-11-11 13:31:15

相關問題