Профиль по умолчанию в Spring 3.1

100

В моем приложении есть bean-компоненты, помеченные значками @Profile("prod")и @Profile("demo"). Первый, как вы можете догадаться :), используется на bean-компонентах, которые подключаются к производственной БД, а второй аннотирует bean-компоненты, которые используют какую-то поддельную БД ( HashMapили что-то еще) - чтобы ускорить разработку.

Я бы хотел иметь профиль по умолчанию ( "prod"), который будет использоваться всегда, если он не заменен « чем-то еще ».

Идеально было бы иметь в моем web.xml:

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>prod</param-value>
</context-param>

а затем переопределите это, -Dspring.profiles.active="demo"чтобы я мог сделать:

mvn jetty:run -Dspring.profiles.active="demo". 

Но, к сожалению, это не работает. Есть идеи, как я могу этого добиться? Установка -Dspring.profiles.active="prod"во всех моих средах не вариант.

Михал Маргил
источник

Ответы:

67

Мой опыт показывает, что использование

@Profile("default")

компонент будет добавлен в контекст только в том случае, если не идентифицирован другой профиль. Если вы переходите в другой профиль, например -Dspring.profiles.active="demo", этот профиль игнорируется.

Пол Филион
источник
4
Принятый ответ зависит от web.xml (и это нормально), но этот ответ работает независимо от того, есть ли у вас web.xml или нет, и поэтому он более полезен для всех.
Джей
1
это решение намного чище
cahen
Это официальная функция или побочный эффект? Хотите ссылку на документацию Spring, где описывается эта функция?
rustyx
111

Определите свою производственную среду как профиль по умолчанию в вашем web.xml

<context-param>
   <param-name>spring.profiles.default</param-name>
   <param-value>prod</param-value>
</context-param>

и если вы хотите использовать другой профиль, передайте его как системное свойство

mvn -Dspring.profiles.active="demo" jetty:run
Andih
источник
3
Нет, он пытался определить активный профиль в web.xml и как системное свойство. В своем решении я настраиваю профиль по умолчанию в web.xml и перезаписываю / определяю активный профиль через системное свойство. Если нет явного активного профиля, будет использоваться значение по умолчанию.
Andih 06
1
Спасибо! это именно то, что я хотел! нигде не нашел: /
Michał Margiel
Одна из проблем , с этим подходом: если вы установите spring.profiles.default=prodв application.properties, то application-prod.propertiesне будет загружен. Это противоречит интуиции.
gamliela
@gamliela Подход не устанавливает профиль по умолчанию в application.propertiesфайле. Чтобы знать, что application-prod.propertiesследует использовать, вам необходимо знать профиль. Вот что делает этот подход. Он определяет профили вне контекста Spring либо через web.xml(по умолчанию), либо через переменную среды (перезаписать по умолчанию).
Andih 01
@andih Да, я знаю это, но я только говорю, что это не интуитивно понятно и, следовательно, проблематично. Поскольку application-default.propertiesзагрузка, я также ожидаю, что application-newdefault.propertiesона также будет загружена. Это не проблема с вашим решением, это проблема со Spring ...
gamliela
6

У меня такая же проблема, но я использую WebApplicationInitializer , чтобы программно настроить ServletContext (Servlet 3.0+). Итак, я делаю следующее:

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        // Create the 'root' Spring application context
        final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        // Default active profiles can be overridden by the environment variable 'SPRING_PROFILES_ACTIVE'
        rootContext.getEnvironment().setDefaultProfiles("prod");
        rootContext.register(AppConfig.class);

        // Manage the lifecycle of the root application context
        sc.addListener(new ContextLoaderListener(rootContext));
    }
}
mcoolive
источник
5

Вы также можете удалить профиль PROD и использовать @Profile ("! Demo")

Blacelle
источник
2
Я полагаю, это не сработает, если у вас более двух профилей, верно?
Чоп
3

О настройке производственного профиля по умолчанию уже опубликовано @andih

Самый простой способ установить профиль по умолчанию для плагина maven jetty - включить следующий элемент в конфигурацию вашего плагина:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
        <systemProperties>
            <systemProperty>
                <name>spring.profiles.active</name>
                <value>demo</value>
            </systemProperty>
        </systemProperties>
    </configuration>
</plugin>
Якуб Кубринский
источник
3

Spring предоставляет два отдельных свойства при определении активных профилей:

  • spring.profiles.active

и

  • spring.profiles.default

Если spring.profiles.activeустановлен, то его значение определяет, какие профили активны. Но если spring.profiles.activeне установлен, то Spring смотрит наspring.profiles.default.

Если ни spring.profiles.activeни spring.profiles.defaultне задано, то активных профилей нет, и создаются только те бины, которые не определены как находящиеся в профиле. Любой бин, который не указывает профиль, принадлежит defaultпрофилю.

Тухидур Рахаман Хан
источник
-1

Вы можете настроить свой web.xml как отфильтрованный ресурс, и maven будет заполнять это значение из настроек профиля maven - это то, что мы делаем.

в pom фильтруйте все ресурсы (вы можете сделать это, если в них нет отметки $ {})

<webResources>
    <resource>
        <directory>src/main/webapp</directory>
        <filtering>true</filtering>
    </resource>
</webResources>

в web.xml положить

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>${spring.prfile}</param-value>
</context-param>

в pom создать профили maven

<profiles>
    <profile>
        <id>DEFAULT</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profile>prod</spring.profile>
        </properties>
    <profile>
    <profile>
        <id>DEMO</id>
        <properties>
            <spring.profile>demo</spring.profile>
        </properties>
    <profile>
</profiles>

Теперь вы можете использовать

mvn jetty:run -P DEMO

или просто -P DEMOс помощью любой команды maven

Hurda
источник
1
Я не уверен, но думаю, что это не сработает. Причал IMHO: run не будет запускать фазу, в которой фильтруются ресурсы.
Michał Margiel
из причин вам нужно запустить mvn clean compile jetty: run -P DEMO, но с некомпилированным кодом он запускает его автоматически
Hurda
10
Я понимаю, что одной из основных целей Spring 3.1 Profiles является создание единого WAR-файла, готового к развертыванию во всех средах. Использование профилей Maven - это шаг назад к предыдущему состоянию: когда упаковка файла WAR требовалась для каждой среды ...
edrabc 03
@edrabc он просил mvn jetty: run - файла WAR нет.
Hurda
Согласитесь @Hurda. Но он также просил запускать команду в нескольких средах: сочетание Maven Profiles и Spring Profiles могло немного вводить в заблуждение ...
edrabc