动态改变春豆

时间:2009-04-28 13:20:35

标签: java spring javabeans

如何使用java spring在运行时动态更改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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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之间存在循环依赖关系,我不确定你的示例配置是否合法。

答案 2 :(得分:1)

使用班级工厂。 可以根据您的财产返回实例。

答案 3 :(得分:1)

我相信你可以编写一个实现BeanFactoryPostProcessor的类。如果XML配置文件中存在此类的bean(与其他bean一起),Spring将自动调用其postProcessBeanFactory(ConfigurableListableBeanFactory)方法。递交给此方法的ConfigurableListableBeanFactory对象可用于在Spring开始工作之前更改任何bean定义。

答案 4 :(得分:1)

同意上面的@Olivier。

有很多方法可以做到。

  1. 使用PropertyPlaceHolderConfigurer ..
  2. 使用BeanPostProcessor ..
  3. 使用Spring AOP,创建建议并操纵属性。
  4. 我建议上面的项目编号为: