Я большой пользователь Spring, и должен признаться, что не следил за всеми последними добавлениями версии 3.1. Одним из таких дополнений является понятие
профиля .
контекст
Профили предназначены для того случая, когда вы используете одну и ту же конфигурацию Spring для всех своих нужд, но когда есть небольшие различия. Наиболее частым случаем использования является источник данных. Например, во время моих интеграционных тестов я не использую сервер приложений, поэтому мой источник данных поступает из простого org.apache.commons.dbcp.BasicDataSource, настроенного с URL, именем класса драйвера, пользователем и паролем, например так:
<bean id="dataSource"> <property name="driverClassName" value="${db.driver}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.username}" /> <property name="password" value="${db.password}" /> </bean>
Обратите внимание, что существуют другие альтернативы BasicDataSource, такие как org.springframework.jdbc.datasource.SingleConnectionDataSource или com.mchange.v2.c3p0.ComboPooledDataSource.
В среде сервера приложений я использую другое определение компонента:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ds" />
Вы, вероятно, заметили, что оба предыдущих определения бина имеют одно и то же имя. Имейте это в виду, это будет играть роль в следующем разделе.
Мое устаревшее решение
Чтобы иметь возможность переключаться с одного компонента на другой в зависимости от контекста, я использую следующее решение:
- Я разделяю определение bean-компонента источника данных в его собственном конфигурационном файле Spring (соответственно spring-datasource-it.xml и spring-datasource.xml)
- Для производственного кода я создаю основной конфигурационный файл Spring, который импортирует последний:
- Для тестирования интеграции я использую класс Spring Test в качестве родительского (например, AbstractTestNGSpringContextTests ) и настраиваю его с помощью аннотации ContextConfiguration . @ContextConfiguration имеет атрибут местоположения, который может быть установлен вместе с расположением всех необходимых фрагментов конфигурации Spring для запуска моего интеграционного теста.
Кроме того, как пользователь Maven, я могу аккуратно хранить файл spring-datasource.xml в src / main / resources и файл spring-datasource-it.xml в src / test / resources или в отдельных модулях. Учитывая это, конечный артефакт содержит только соответствующий компонент источника данных сервера приложений в моей конфигурации Spring: базовый пул данных безопасно остается в моем тестовом коде.
Профильное решение
Помните, когда идентификаторы бина должны были быть уникальными во всей конфигурации Spring, это уже не так. С помощью профилей к каждому компоненту (или, точнее, к группе компонентов) можно добавить дополнительную информацию о профиле, чтобы идентификаторы компонента были уникальными для всего профиля. Это означает, что мы можем определить два bean-компонента с идентификатором источника данных и установить профиль для каждого: Spring не будет жаловаться. Если мы вызовем интеграцию этих профилей и сервер приложений и при необходимости активируем их в коде, это будет иметь точно такие же результаты. Файл конфигурации Spring будет выглядеть так:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="..."> ... <beans profile="integration"> <bean id="dataSource"> <property name="driverClassName" value="${db.driver}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.username}" /> <property name="password" value="${db.password}" /> </bean> </beans> <beans profile="production"> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ds" /> </beans> </beans>
Теперь конфигурационный файл Spring содержит оба контекста.
Вывод
Я не совсем уверен, что такое использование профилей приносит что-то на стол (несмотря на то, что пример источника данных изображен повсюду в Интернете). Конечно, мы перешли от конфигурации времени сборки к конфигурации времени исполнения. Но единственное следствие, которое я вижу, состоит в том, что последние артефакты отправляются с информацией, не имеющей отношения к окружающей среде: в лучшем случае это плохая практика, а в худшем — недостаток безопасности.
Другие варианты использования могут включать необходимость запуска приложения как на сервере приложений, так и в облаке. Даже тогда я бы высказался за отдельные файлы конфигурации, собранные во время сборки. Я думаю, что я останусь с моим устаревшим подходом на данный момент, по крайней мере, до тех пор, пока я не окажусь неправым или пока не представится случай, который можно легко решить с помощью профилей без побочных эффектов.