2009-04-28 121 views
6

如何在运行时使用java弹簧动态更改bean的属性? 我有一个bean mainView,应该使用属性“class”“class1”或“class2”。 这个决定应该基于属性文件进行,其中属性“withSmartcard”为“Y”或“N”。动态更改弹簧豆

的ApplicationContext:

<bean id="mainView" 
    class="mainView"> 
    <property name="angebotsClient" ref="angebotsClient" /> 
    <property name="class" ref="class1" /> 
</bean> 



<bean id="class1" 
    class="class1"> 
    <constructor-arg ref="mainView" /> 
</bean> 

<bean id="class2" 
    class="class2"> 
    <constructor-arg ref="mainView" /> 
</bean> 

PropertyFile:

withSmartcard = Y

回答

1

使用类工厂。 它可以基于你的财产返回实例。

10

使用PropertyPlaceHolder来管理您的属性文件..

<bean id="myPropertyPlaceHolder" 
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <description>The service properties file</description> 
    <property name="location" value="classpath:/some.where.MyApp.properties" /> 
    </bean> 

,改变你的ref属性如下:

<bean id="mainView" 
    class="mainView"> 
    <property name="angebotsClient" ref="angebotsClient" /> 
    <property name="class" ref="${withSmartCardClassImplementation}" /> 
</bean> 

在你的属性文件some.where.MyApp.properties,加键名为withSmartCardClassImplementation,它将具有class1或class2(您选择)作为值。

withSmartCardClassImplementation=class1 
+0

它应该是{$ classIdToBeUsed}还是$ {classIdToBeUsed}? – 2009-04-28 13:35:30

+0

$ {classIdToBeUsed} :)错字,谢谢!显然,我改变classIdToBeUsed forSmartCardClassImplementation – Olivier 2009-04-28 13:39:28

4

您想要PropertyPlaceholderConfigurer。该手册的这一部分比我现场可以更好地展示它。

在您的示例中,您需要将属性的值更改为class1class2(春季上下文中所需bean的名称)。

或者,你的配置可能是:

<bean id="mainView" 
    class="mainView"> 
    <property name="angebotsClient" ref="angebotsClient" /> 
    <property name="class"> 
     <bean class="${classToUse}"> 
      <constructor-arg ref="mainView"/> 
     </bean> 
    </property> 
</bean> 

与包含配置文件: classToUse = fully.qualified.name.of.some.Class

使用Bean或类名也不会在用户可编辑的配置文件中可以接受,而且您确实需要使用“Y”和“N”作为配置参数值。在这种情况下,你只需要用Java来做到这一点,Spring并不打算完成。

MAINVIEW可以访问直接应用程序上下文:

if (this.withSmartCards) { 
    this.class_ = context.getBean("class1"); 
} else { 
    this.class_ = context.getBean("class2"); 
} 

一个清洁的解决方案是在它自己的类被包封用户配置的处理,将执行上述操作,以减少需要被了ApplicationContextAware类的数量并根据需要将其注入到其他课程中。

使用BeanFactoryPostProcessor,您可以以编程方式注册类属性的定义。使用FactoryBean,您可以动态创建一个bean。两者都是Spring的一些先进用法。

另一方面:我不确定您的示例配置是否合法,因为mainView和class1/class2之间存在循环依赖关系。

1

同意上面的@Olivier。

有很多方法可以做到这一点。

  1. 使用PropertyPlaceHolderConfigurer ..
  2. 使用的BeanPostProcessor ..
  3. 使用Spring AOP中,创建一个意见和操纵性能。

我会推荐以上的产品编号:1。