Простая поддержка окружений в Spring 3.1+

от автора

Многие знают что для подстановки значений в конфигурационные файлы Spring можно использовать context:property-placeholder.

<context:property-placeholder location="classpath*:/prop/*.properties"/> <!-- здесь будут искаться property файлы -->  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">     <constructor-arg ref="mongo"/>     <constructor-arg name="databaseName" value="${mongo.db}"/> <!-- здесь будет подставлено значение из найденных property --> </bean> 

Но, при данном подходе, можно лишь подставить различные значения параметров, но не изменить логику развертывания контекста. А ведь, в некоторых случаях, нам необходимо развернуть огромную систему, интегрированную с внешними системами, а в некоторых — просто одну маленькую заглушку.

Когда передо мной встала задача, в зависимости от окружения (dev, prod, load-test), изменить логику развертывания — я искренне попытался использовать старый проверенный способ через property.

И я сделал следующее:

Я создал 2 различных контекста: my-prod.xml и my-test.xml и вот такой свитчер:

<context:property-placeholder location="classpath*:/prop/*.properties"/>  <import resource="classpath*:my-${proj.env}.xml"/> <!-- наивная попытка воспользоваться вставкой property при импорте конфига --> 

Но разработчики Spring знали о моем намерении заранее, намного заранее.

Итак, разрулить с помощью property использование различных конфигов в контексте, в зависимости от окружения, невозможно.
На этом можно было бы и закончить рассказ если бы в Spring 3.1 не появились Environment‘ы.

Как это работает:
Вам просто нужно придумать набор профилей и разметить ими свои конфиги, либо наделать вот таких свитчей импорта:

<beans profile="test"> <!-- будет задействовано при запуске с профилем "test" -->     <import resource="classpath*:/my-test.xml"/> </beans> <beans profile="prod,dev"> <!-- HE будет задействовано при запуске с профилем "test" -->     <import resource="classpath*:/my-prod.xml"/>  </beans> 

Запуск:
Есть два варианта запуска:

1) Через экземпляр контекста:

ClassPathXmlApplicationContext сontext = new ClassPathXmlApplicationContext(new String[]{"classpath*:bean.xml"}, false); сontext.getEnvironment().setActiveProfiles("test"); сontext.refresh(); 

2) Через Unit-test:

@ContextConfiguration(locations = {"classpath*:bean.xml"}) @ActiveProfiles(profiles = {"test"}) @RunWith(SpringJUnit4ClassRunner.class) public class SuperTest { ... 

Да, все так просто 😉

P.s. Англоязычная статья

ссылка на оригинал статьи http://habrahabr.ru/post/156731/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *