2010-11-11 27 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

相关问题