Spring spring.profiles.include переопределяет

Мое намерение состоит в том, чтобы иметь два профиля в приложении весенней загрузки - разработку и производство. Профиль разработки предназначен только для переопределения некоторых переменных производственного профиля (например, базы данных в памяти вместо базы данных в облаке). Поскольку я ожидаю, что в будущем в производственный профиль будут внесены некоторые изменения, дублирование переменных в профиле разработки не кажется решением.

Итак, в Spring Reference Я читал, что spring.profiles.include должен добавлять свойства только из профиля, на который указывает ссылка.

Иногда полезно иметь специфические для профиля свойства, которые дополняют активные профили, а не заменяют их. Свойство spring.profiles.include можно использовать для безусловного добавления активных профилей.

Однако из того, что я проверил, это скорее отменяет его. Итак, при наличии двух профилей foo и bar в отдельных файлах yaml:

приложение-foo.yaml:

myproperty: 44

приложение-bar.yaml:

spring:
  profiles:
    include: foo
    active: bar,foo
myproperty: 55

И установка переменной -Dspring.profiles.active=bar в IDE, значение времени выполнения myproperty равно 44. Это означает, что bar переопределяется с помощью foo, который должен был только добавлять свойства, но не переопределять их. При запуске приложения получаю:

Активны следующие профили: foo,bar

Я добавил spring.profiles.active=bar к application-bar.yaml, как было предложено в этом ответе в другом вопросе, но это не имеет никакого эффекта - нет никакой разницы, когда свойство есть или нет (я также пытался использовать тире вместо значений, разделенных запятыми).

Мой вопрос в том, как это должно работать (тогда Spring Reference вводит в заблуждение)? Если да, то есть ли решения для этого?

Добавление ссылки на исходный код приложения на github.


person Daniel Szymatowicz    schedule 18.11.2017    source источник


Ответы (5)


Мы реализовали активные профили Spring немного по-другому. Допустим, файл свойств по умолчанию, application.yml, содержит все значения по умолчанию, одинаковые как в рабочей среде, так и в среде разработки.

Создайте отдельные свойства для рабочих файлов и файлов разработки с именами application-prd.yml и application-dev.yml соответственно. Эти файлы могут содержать дополнительные свойства или переопределять некоторые свойства по умолчанию.

Во время запуска приложения мы передаем spring.profiles.active в качестве переменной среды. Например,

-Dspring.profiles.active=prd

заберет application-prd.yml вместе с application.yml

or

-Dspring.profiles.active=dev

заберет application-dev.yml вместе с application.yml

person Indra Basak    schedule 19.11.2017
comment
Спасибо, я думаю, что это достаточно хорошо для моей цели. Это по-прежнему не дает разработчику возможности переопределять файлы пользовательских свойств, поэтому мне приходится создавать дополнительный файл (в конце концов есть application.yaml, application-foo.yaml и application-bar.yaml), но до тех пор, пока я могу удовлетворить требование его штраф. - person Daniel Szymatowicz; 19.11.2017

Согласно документации по весенней загрузке здесь spring.profiles.include используется для добавления свойств из других профилей. Он добавит свойство из других профилей, если свойство отсутствует в активном. Но если он присутствует, то он перезапишется и побеждает последний примененный

Иногда полезно иметь специфические для профиля свойства, которые дополняют активные профили, а не заменяют их. Свойство spring.profiles.include можно использовать для безусловного добавления активных профилей.

person pvpkiran    schedule 18.11.2017
comment
Я знаю ссылку - в ней упоминается свойство spring.profiles.include, которое можно использовать для безусловного добавления активных профилей. - это описание неоднозначно для меня. Но это нормально, есть ли способ просто импортировать настройки из другого профиля, но не заставлять их переопределять текущий? - person Daniel Szymatowicz; 18.11.2017

Вы можете добавить новый профиль в application-bar.yaml:

spring.profiles.include: foo,foo-override
myproperty: 33

---
spring.profiles: foo-override
myproperty: 55

Порядок следующий: 33 in bar перекрывается 44 in foo переопределяется 55 in foo-override.

person ywy    schedule 22.11.2019

Spring Boot 2.4 изменяет механизм включения нескольких профилей для использования нового группы профилей вместо использования spring.profiles.include в документе, относящемся к профилю. Это означает, что ваша конфигурация больше не действительна для новых версий Spring Boot, и ее необходимо изменить.

Тем не менее, ваш вариант использования не очень подходит для групп профилей, поскольку на самом деле он не столько объединяет два профиля, сколько переопределяет значения по умолчанию. Поэтому я рекомендую использовать подход, предложенный в другом ответе, чтобы поместить общие свойства и свойства по умолчанию в общий файл application.yaml и только включая значения и переопределения для конкретных сред в документах для конкретных профилей.

application.yaml

spring:
  myproperty: 44 # Default value

application-bar.yaml

spring:
  myproperty: 55 # Override default

Обратите внимание, что Spring Boot поддерживает многодокументные файлы, поэтому при желании их можно объединить в один application.yaml файл:

spring:
  myproperty: 44 # Default value
---
spring.config.activate.on-profile=bar # These configs apply to the bar profile
spring:
  myproperty: 55 # Override default

Соответствующие 2.4 Изменения

Начиная с Spring Boot 2.4 больше нельзя использовать spring.profiles.include в документе для конкретного профиля, если только устаревший режим включается с помощью spring.config.use-legacy-processing=true. Согласно Spring 2.4. Руководство по переносу данных конфигурации загрузки:

вы по-прежнему можете использовать свойство spring.profiles.include, но только в документах, не относящихся к профилю.

Этот подход был заменен группы профилей. Согласно руководству по миграции. :

Как обсуждалось выше, больше нельзя использовать spring.profiles.include в документе, относящемся к профилю, поэтому этот файл недействителен.

Поскольку этот вариант использования довольно распространен, мы попытались предоставить другой способ его поддержки. В Spring Boot 2.4 вы можете использовать "группы профилей".

Эта функция описана в Группы профилей справочного руководства по Spring Boot:

Группа профилей позволяет определить логическое имя для связанной группы профилей.

Например, мы можем создать группу production, состоящую из наших профилей proddb и prodmq.

spring:
  profiles:
    group:
      production:
      - "proddb"
      - "prodmq"

Теперь наше приложение можно запустить с помощью --spring.profiles.active=production, чтобы активировать профили production, proddb и prodmq одним нажатием.

Руководство по миграции указывает out, что свойство spring.profile.group нельзя использовать в документах, относящихся к профилю.

Свойство spring.profile.group нельзя использовать в документах, относящихся к профилю.

person M. Justin    schedule 05.04.2021

Данный:

  • Файлы: application-default.yml, application-foo.yml, application-bar.yml
  • myproperty: default в файле application-default.yml
  • myproperty: foo в приложении-foo.yml
  • myproperty: bar в файле application-bar.yml

Я думаю, что эти 2 варианта использования профилей немного противоположны по смыслу:

  1. В наиболее распространенном случае (-Dspring.profiles.active, но не spring.profiles.include):

    1. When profile foo or boo are activated the properties from application-foo.yml (or application-bar.yml) will add/override the ones from application-default.yml.
    2. Когда профили foo,bar активированы, свойства из bar будут добавлять/переопределять свойства из application-foo.yml, а затем свойства из application-default.yml.

    Например: -Dspring.profiles.active=foo,bar свойство из application-bar.yml выигрывает (переопределяет) -> myproperty: bar

  2. Во втором случае (используется spring.profiles.include)

    1. The properties from the include statement add/overrides the properties from the application-*.yml files which uses spring.profiles.include

    То есть: если application-boo.yml содержит spring.profiles.include=foo, то свойства из application-foo.bar adds/override properties from from application-bar.yml добавляют/переопределяют свойства из application-default.yml.

    С другой стороны (я полагаю), если application-boo.yml включает spring.profiles.include=default,foo, тогда свойства из application-foo.yml будут добавлять/переопределять свойства из application-default.yml, которые добавляют/переопределяют свойства из application-bar.yml. Итак, myproperty: bar. Я бы не рекомендовал использовать default в сочетании с spring.profiles.include, потому что таким образом он смешивает два случая, а стратегия переопределения нелогична, учитывая, что application-default.yml имеет специальную обработку в springboot.

Я также признаю, что мне совсем не нравится использование spring.profiles.active в файлах application-*.yml. Я предпочитаю активировать профили с системными свойствами (включая maven) или переменными env. ИМО, это делает все профили более понятными для меня.

Если с моими (здесь выше) рассуждениями я на неправильном пути, пожалуйста, дайте мне знать.

person jtonic    schedule 09.11.2020