Элегантное решение, упомянутое в вопросе, будет выглядеть следующим образом: Оно не сильно отличается от других решений, но на самом деле невозможно с текущим UML, поскольку Свойство end end имеет isUnique=true
: Я думаю, это ошибка спецификации. Это, безусловно, можно исправить (показано синим цветом). Тем не менее, кажется, что эта ошибка не была замечена очень часто. Будет ли это исправление достаточно полезным, чтобы стоить усилий?
Если за этот ответ проголосуют, я подам вопрос.
Используйте 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
Согласитесь с @Olivier выше.
Есть много способов сделать это.
Я бы порекомендовал элемент №: 1 выше.
Требуется 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 = полностью.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 , вы можете динамически создавать бин.
Использовать фабрику классов. который может вернуть экземпляр на основании вашей собственности.
Я полагаю, вы можете написать класс, который реализует BeanFactoryPostProcessor . Если bean-компонент этого класса существует в файле конфигурации XML (вместе с другими вашими bean-компонентами), Spring автоматически вызовет свой метод postProcessBeanFactory (ConfigurableListableBeanFactory) . Объект ConfigurableListableBeanFactory , переданный этому методу, можно использовать для изменения любых определений бинов до того, как Spring приступит к их инициализации.