Spring: переопределение свойств в дочернем контексте во время выполнения - PullRequest
4 голосов
/ 12 января 2012

В родительском контексте у меня есть объявление свойств следующим образом:

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

После этого во время выполнения мне нужно создать дочерний контекст и переопределить эти свойства данными времени выполнения. Каков наилучший способ сделать это?

Сложение:

Точнее, я создаю дочерний контекст вручную во время выполнения, как это:

ClassPathXmlApplicationContext childAppContext = new ClassPathXmlApplicationContext(parentApplicationContext);

Итак, можно ли объявить bean-компонент в childAppContext, как это обычно делается с BeanDefinitionRegistry?

Ответы [ 2 ]

1 голос
/ 12 января 2012

Похоже, у вас есть подкласс 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» в bean-компонент PropertyPlaceholderConfigurer, определенный в файле контекста клиента. Дальнейшее копание может привести к лучшему решению, это не типичный вариант использования, я уверен, вы продвинетесь дальше.

0 голосов
/ 13 сентября 2013

Прорабатывая ответ mrembisz, вот полный пример динамического внедрения свойств в контекст Spring без жесткого кодирования любого компонента внутри дочернего XML и последующей передачи ссылки на компонент из родительского контекста. Приведенное ниже решение не требует определения родительского контекста для этой цели.

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"));
}
...