Spring:在运行时覆盖子上下文中的属性

时间:2012-01-12 11:54:27

标签: spring properties runtime override applicationcontext

在父上下文中,我有如下属性声明:

<bean id="my.properties"
        class="com.rcslabs.webcall.server.property.PropertyPaceholderConfigurer">
        <property name="locations" value="classpath:/my.properties"/>
</bean>

在运行时之后,我需要创建一个子上下文,并使用运行时数据覆盖这些属性。最好的方法是什么?

此外:

更确切地说,我在运行时手动创建子上下文,如下所示:

ClassPathXmlApplicationContext childAppContext = new ClassPathXmlApplicationContext(parentApplicationContext);

那么,我可以在childAppContext中声明一个bean,就像通常使用BeanDefinitionRegistry一样吗?

2 个答案:

答案 0 :(得分:1)

看起来你有一个PropertyPlaceholderConfigurer的子类,为什么不用逻辑检查运行时值来覆盖resolveProperty,否则又回到默认值?您可能必须为子上下文创建一个专用子类,并在其中注入运行时值源。

您还可以执行的操作是将运行时值放在系统属性中,并使用覆盖模式systemPropertiesMode。这是一个简单但不太干净的解决方案,我的第一种方法的一些变化会更好。如果您创建多个客户端上下文,只要您不并行生成它们,它就会起作用。

更新:我会从以下内容开始:

final Map<String,String> myRuntimeValues;

ClassPathXmlApplicationContext childAppContext = new ClassPathXmlApplicationContext(parentApplicationContext) {
  protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.prepareBeanFactory();
    beanFactory.registerSingleton("myRuntimeValues", myRuntimeValues);
  }
};

并将“myRuntimeValues”注入到客户端上下文文件中定义的PropertyPlaceholderConfigurer bean中。更多的挖掘可能会产生更好的解决方案,这不是一个典型的用例,我相信你会更进一步。

答案 1 :(得分:0)

在阐述mrembisz的答案时,这里是动态地将属性注入spring上下文的完整示例,无需在子xml中对任何bean进行硬编码,然后从父上下文传递bean引用。以下解决方案不需要为此目的定义父上下文。

public static void main(String args[]) {
    AbstractApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "classpath:spring-beans.xml" }) {
        protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            super.prepareBeanFactory(beanFactory);
            ArrayList<Properties> prList = new ArrayList<Properties>();
            Properties pr = new Properties();
            pr.setProperty("name", "MyName");
            prList.add(pr);
            Properties prArray[] = new Properties[prList.size()];
            PropertySourcesPlaceholderConfigurer pConfig = new PropertySourcesPlaceholderConfigurer();
            pConfig.setPropertiesArray(prList.toArray(prArray));
            beanFactory.registerSingleton("pConfig", pConfig);
        }
    };
    appContext.refresh();
    System.out.println(appContext.getBean("name"));
}