4

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

<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 一样吗?

4

2 回答 2

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。更多的挖掘可能会产生更好的解决方案,这不是典型的用例,我相信你会走得更远。

于 2012-01-12T12:19:59.510 回答
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"));
}
于 2013-09-13T07:52:10.957 回答