Разрешает ли Spring преобразовывать абстрактный bean-компонент в non-abstract? - PullRequest
1 голос
/ 29 октября 2011

Мое приложение может работать в разных средах.Мне нужно настроить модель данных для каждой среды.Модель данных строится с использованием Spring bean.

Я использую Spring 3.0.5, поэтому не могу условно загрузить ресурсы.У меня есть это:

<bean id="Template1" class="...
..............
</bean>

<bean id="Template2" class="...
..............
</bean>

<bean id="Template3" class="...
..............
</bean>
................

<bean id="Factory" ...>
<propety name="type"><value>${app.type}</value></property>
<property>
 <map>
   <entry key="Temlate1" value-ref="Template1">
   <entry key="Temlate2" value-ref="Template1">
   <entry key="Temlate3" value-ref="Template1">

..................

Реальный бин, который я создаю фабрикой:

<bean id="real" factory="Factory" factory-method="getInstance"
 <constructor-arg>Factory</.....
 .............
 </bean>

Java-код:

class Factory {
private Map<String, Object> templateBeans;

 Object getInstance(String name) {
  return templateBeans.get(name);
 ...........

Можно ли как-то объявить абстрактныйшаблон фасоли?Потому что у меня очень большая проблема с памятью.Существует ли другой способ создания экземпляров различных bean-компонентов условно в Spring до версии 3.1?Было бы хорошо использовать только EL, потому что у меня нет доступа к Java-коду бинов, так как они из сторонней библиотеки.

Ответы [ 6 ]

5 голосов
/ 07 ноября 2011

Я не пробовал этого, но я вполне уверен, что вы могли бы использовать псевдонимы bean для этого.

Сначала объявите все ваши bean-компоненты шаблона, чтобы они не создавались при запуске.

Затем используйте псевдоним bean-компонента с переменной, чтобы указать на реальный:

<alias name="real" alias="${beanForEnvironment}"/>

Смотрите мой ответ здесь, чтобы узнать, как красиво загрузить свойства для среды:местожительство из другого имущества

1 голос
/ 07 ноября 2011

Я сталкивался с этой проблемой раньше, и чтобы обойти ее, я использую тег импорта Spring. Например:

<import resource="file:/location/to/your/config/my_beans.xml"/>

Это позволяет вам выводить конфигурацию Spring XML из вашего приложения war / jar. Таким образом, в вашей ситуации вам придется развертывать различные внешние настройки XML для Spring в каждой из ваших сред, но это также позволяет вам создавать именно те компоненты, которые вы хотите.

0 голосов
/ 12 ноября 2011

Как подсказывает Толиций, аргументы времени выполнения работают нормально. Вы можете передать -Dyourvar = yourvalue в среду выполнения Java, и вы можете использовать $ {yourvar} в своих весенних импорте Если он не установлен, вы получите сообщение об ошибке «ресурс не найден».

Если это отдельная программа: java YourClass -Dyourvar = yourvalue Когда вы используете сервер приложений, вы также можете установить аргументы времени выполнения. Поиск документации по серверам о том, как увеличить память серверов. Место, где вы можете установить параметр -Xmx, обычно будет местом, где вы также можете установить константу -Dyourvar.

0 голосов
/ 11 ноября 2011

Использовать ленивый init lazy-init="true" Но, может быть, бины получают экземпляры, как только на них ссылаются в Map, поэтому используйте Map of String с именем экземпляров, чтобы фабрика запрашивала их в контексте приложения по коду.context.getBean(MyInterface.class, templates.get(name));

0 голосов
/ 08 ноября 2011

Если вы можете перейти на Spring 3.1, вы получите profies

В случае, если обновление не вариант, взгляните на использование системных переменных (например, $ {ENV_SYSTEM: dev}) для переключения между конфигурациями (свойствами).

Еще один хороший SO - Общие стратегии при определении бинов Spring для различных сред

напримересли у вас есть bean-компоненты разработки в service-development.xml, импортируйте их как:

<import resource="service-${profile}.xml"/>

и начните с -Dprofile=development.Или когда вы переходите в QA: -Dprofile=qa

0 голосов
/ 07 ноября 2011

Чистое решение, если возможно, состоит в том, чтобы не использовать Factory, а использовать разные конфигурационные файлы для разных сред, определяющих один и тот же «реальный» компонент, но с разными реализациями. Во время выполнения вы просто импортируете правильную версию, например, шаблон. $ {app.type} .xml.

Другое, более уродливое решение для этого состоит в том, чтобы сделать ваши bean-init-bean-компоненты шаблона и гарантировать, что они создаются динамически. Вы не можете внедрить их в карту на фабрике, потому что это все равно их создало бы. Вместо этого вы можете сохранить карту beanNames и создать свой Factory ApplicationContextAware. Затем в методе getInstance () вернуть applicationContext.getBean (beanNames.get (...));

Более сложным решением было бы смешать XML-конфигурацию с Spring JavaConfig, которая позволяет вам использовать всевозможную логику в ваших определениях bean-компонентов.

...