динамически менять весенние бобы - PullRequest
6 голосов
/ 28 апреля 2009

как мне динамически изменять свойства bean-компонента во время выполнения, используя java spring? У меня есть 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 ]

10 голосов
/ 28 апреля 2009

Используйте 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
4 голосов
/ 28 апреля 2009

Требуется PropertyPlaceholderConfigurer . Этот раздел руководства демонстрирует это лучше, чем я мог на месте.

В вашем примере вам необходимо либо изменить значение свойства на class1, либо class2 (имя нужного компонента в контексте весны).

Альтернативно, ваша конфигурация может быть:

<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

Использование имен бинов или классов недопустимо в редактируемом пользователем файле конфигурации, и вам действительно нужно использовать «Y» и «N» в качестве значений параметров конфигурации. В этом случае вам просто нужно будет сделать это на Java, Spring не предназначен для полного тестирования.

mainView может напрямую обращаться к контексту приложения:

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

Более чистое решение заключалось бы в инкапсуляции обработки пользовательской конфигурации в своем собственном классе, которая выполняла бы вышеописанное, чтобы уменьшить количество классов, которые должны быть ApplicationContextAware, и внедрять их в другие классы по мере необходимости.

Используя BeanFactoryPostProcessor , вы можете зарегистрировать определение свойства класса программно. Используя FactoryBean , вы можете динамически создавать бин. Оба - несколько продвинутые способы использования Spring.

В сторону: я не уверен, допустим ли ваш пример конфигурации, учитывая циклическую зависимость между mainView и class1 / class2.

1 голос
/ 28 апреля 2009

Согласен с @Olivier выше.

Есть много способов сделать это.

  1. Использовать PropertyPlaceHolderConfigurer ..
  2. Использовать BeanPostProcessor ..
  3. Используйте Spring AOP, создайте совет и управляйте свойствами.

Я бы порекомендовал пункт № 1 выше.

1 голос
/ 28 апреля 2009

Полагаю, вы можете написать класс, который реализует BeanFactoryPostProcessor . Если bean-компонент этого класса существует в файле конфигурации XML (наряду с другими вашими bean-компонентами), Spring автоматически вызовет его метод postProcessBeanFactory (ConfigurableListableBeanFactory) . Объект ConfigurableListableBeanFactory , переданный этому методу, можно использовать для изменения любых определений бинов до того, как Spring приступит к их инициализации.

1 голос
/ 28 апреля 2009

Используйте класс фабрики. который может вернуть экземпляр на основании вашей собственности.

...