Мы используем импорт с подстановочными символами в модулях, чтобы позволить другим модулям добавлять бины в модуль, объявляющий импорт:
<import resource="classpath*:com/acme/**/*-core-support.xml" />
Модульность
Модули, которые хотят внести свой вклад в «хост», просто должны поместить файлы с правильными именами в src/main/resources/com/acme
, чтобы в этом случае они были собраны автоматически. Если вы используете сканирование пути к классам (к <context:component-scan />
это станет еще проще).
Еще одна вещь, которая помогает в этом отношении, - это небольшое расширение Spring, которое собирает bean-компоненты определенного типа и снова публикует их в ApplicationContext
. Делая что-то вроде этого:
<plugin:list id="beanList" class="com.acme.MyCoolPluginInterface" />
<bean class="com.acme.MyPluginHost">
<property name="plugins" ref="beanList" />
</bean>
В сочетании с импортом с подстановочными символами это будет:
- Соберите все компоненты, найденные в
ApplicationContext
, которые реализуют MyCoolPluginInterface
, и оберните их в список, зарегистрированный как beanList
в ApplicationContext
.
- Разрешить
MyPluginHost
ссылаться на этот список.
Фактически, теперь вы можете просто расширить свое приложение, добавив подключаемые модули в classpath (он же зависимость в Maven).
Это крошечное расширение Spring называется Spring Plugin и публикуется под лицензией Apache 2. См. http://github.com/SpringSource/spring-plugin для получения дополнительной информации. Есть также более продвинутый пример проекта на Github, который показывает, как это работает и улучшает модульность на GitHub. Приложение представляет собой пример кода для моего "Упс! Куда делась моя архитектура?" презентацию, которую вы можете посмотреть слайды здесь или посмотреть запись здесь .
Различные среды
Обычно мы настраиваем наши приложения для работы в целевой среде (с использованием поиска JNDI и прочего). Конечно, вы хотели бы использовать стандартные механизмы PropertyPlaceholderConfigurer
для вывода конфигурации, которая должна быть затронута администраторами или будет изменяться в различных средах.
Для интеграционных тестов у нас обычно есть дополнительные файлы конфигурации в src/main/test
, которые загружаются дополнительно к обычным файлам конфигурации , переопределяя критические компоненты, которые связывают конфигурацию с окружающей средой. Например. если у вас есть источник данных в вашем обычном конфигурационном файле
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
вы бы переопределили это в вашем test-context.xml
, используя
<bean id="dataSource" class="...DataSource" />
<!-- config -->
</bean>
и импорт этого после исходного в тестовом классе
@ConfigurationContext(locations = {"app-context.xml", "test-context.xml"})
public FooBarIntegrationtest {
// ...
}