Standardprofil im Frühjahr 3.1

100

In meiner Anwendung habe ich Bohnen mit @Profile("prod")und kommentiert @Profile("demo"). Die erste wird, wie Sie sich vorstellen können :), für Beans verwendet, die eine Verbindung zur Produktions-DB herstellen, und die zweite kommentiert Beans, die eine gefälschte DB ( HashMapoder was auch immer) verwenden, um die Entwicklung zu beschleunigen.

Was ich haben möchte, ist das Standardprofil ( "prod"), das immer verwendet wird, wenn es nicht von " etwas anderem " überschrieben wird .

Perfekt wäre in meinem web.xml:

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

und überschreibe dies dann mit, -Dspring.profiles.active="demo"damit ich tun kann:

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

Aber leider funktioniert das nicht. Irgendeine Idee, wie ich das erreichen könnte? Das Einstellen -Dspring.profiles.active="prod"in allen meinen Umgebungen ist keine Option.

Michał Margiel
quelle

Antworten:

67

Meine Erfahrung ist das mit

@Profile("default")

Die Bean wird nur dann zum Kontext hinzugefügt, wenn kein anderes Profil identifiziert wurde. Wenn Sie beispielsweise ein anderes Profil übergeben, -Dspring.profiles.active="demo"wird dieses Profil ignoriert.

Paul Philion
quelle
4
Die akzeptierte Antwort hängt von web.xml ab (und das ist in Ordnung), aber diese Antwort funktioniert unabhängig davon, ob Sie web.xml haben oder nicht, und ist daher für alle allgemeiner nützlich.
Jay
1
Diese Lösung ist viel sauberer
Cahen
Ist dies eine offizielle Funktion oder eine Nebenwirkung? Möchten Sie einen Link zur Spring-Dokumentation erstellen, in der diese Funktion beschrieben wird?
Rustyx
111

Definieren Sie Ihre Produktionsumgebung als Standardprofil in Ihrer web.xml

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

und wenn Sie ein anderes Profil verwenden möchten, übergeben Sie es als Systemeigenschaft

mvn -Dspring.profiles.active="demo" jetty:run
andih
quelle
3
Nein, er hat versucht, das aktive Profil in der Datei web.xml und als Systemeigenschaft zu definieren . In meiner Lösung konfiguriere ich ein Standardprofil in der Datei web.xml und überschreibe / definiere das aktive Profil über die Systemeigenschaft. Wenn kein explizites aktives Profil vorhanden ist, wird die Standardeinstellung verwendet.
Andih
1
Vielen Dank! genau das wollte ich! konnte es nirgendwo finden: /
Michał Margiel
Ein Problem bei diesem Ansatz: Wenn Sie setzen spring.profiles.default=prodin application.properties, dann application-prod.propertieswird nicht geladen werden. Dies ist nicht intuitiv.
Gamliela
@gamliela Der Ansatz legt nicht das Standardprofil in einer application.propertiesDatei fest. Um zu wissen, dass application-prod.propertiesdies verwendet werden soll, müssen Sie das Profil kennen. Genau das macht dieser Ansatz. Es definiert Profile außerhalb des Federkontexts entweder als web.xml(Standard) oder über die Umgebungsvariable (überschreibt den Standard).
Andih
@andih Ja, das weiß ich, aber ich sage nur, dass es nicht intuitiv und daher problematisch ist. Da application-default.propertiesich geladen werde, erwarte ich auch, dass application-newdefault.propertiesdas auch geladen wird. Es ist kein Problem mit Ihrer Lösung, es ist ein Problem mit Spring ...
Gamliela
6

Ich habe das gleiche Problem, verwende jedoch WebApplicationInitializer, um den ServletContext programmgesteuert zu konfigurieren (Servlet 3.0+). Also mache ich folgendes:

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
quelle
5

Sie können auch das PROD-Profil entfernen und @Profile ("! Demo") verwenden.

Blacelle
quelle
2
Ich nehme an, das würde nicht funktionieren, wenn Sie mehr als zwei Profile haben, oder?
Chop
3

Informationen zum Festlegen des bereits veröffentlichten Standardproduktionsprofils @andih

Der einfachste Weg, das Standardprofil für das Maven Jetty Plugin festzulegen, besteht darin, das folgende Element in Ihre Plugin-Konfiguration aufzunehmen:

<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>
Jakub Kubrynski
quelle
3

Spring bietet zwei separate Eigenschaften, wenn Sie bestimmen, welche Profile aktiv sind:

  • spring.profiles.active

und

  • spring.profiles.default

Wenn spring.profiles.activegesetzt, bestimmt sein Wert, welche Profile aktiv sind. Aber wenn spring.profiles.activenicht eingestellt, dann sieht Spring nachspring.profiles.default.

Wenn weder spring.profiles.activenoch festgelegt spring.profiles.defaultist, gibt es keine aktiven Profile, und es werden nur die Beans erstellt, die nicht als in einem Profil definiert definiert sind. Jede Bean, die kein Profil angibt, gehört zum defaultProfil.

Touhidur Rahaman Khan
quelle
-1

Sie können Ihre web.xml als gefilterte Ressource einrichten und diesen Wert von maven aus den Maven-Profileinstellungen ausfüllen lassen - genau das tun wir.

im POM-Filter alle Ressourcen (Sie können dies tun, wenn Sie keine $ {} -Markierung haben)

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

in web.xml setzen

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

In Pom erstellen Sie Maven-Profile

<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>

Jetzt können Sie verwenden

mvn jetty:run -P DEMO

oder einfach -P DEMOmit einem beliebigen Maven-Befehl

Hurda
quelle
1
Ich bin mir nicht sicher, aber ich denke, das wird nicht funktionieren. IMHO-Anlegestelle: run führt keine Phase aus, in der Ressourcen gefiltert werden.
Michał Margiel
Natürlich müssen Sie mvn clean compile jetty ausführen: -P DEMO ausführen, aber mit nicht kompiliertem Code wird es
automatisch ausgeführt
10
Ich verstehe, dass eines der Hauptziele von Spring 3.1-Profilen darin besteht, eine einzelne WAR-Datei zu generieren, die in allen Umgebungen bereitgestellt werden kann. Die Verwendung von Maven-Profilen ist ein Schritt zurück zum vorherigen Status: wo das
Packen
@edrabc er fragte nach mvn jetty: run - es gibt keine WAR-Datei.
Hurda
Stimmen Sie @Hurda zu. Er bat aber auch darum, den Befehl in mehreren Umgebungen
auszuführen