Wie erhalten Sie im Frühjahr programmgesteuert das aktuelle Aktiv / Standard-Umgebungsprofil?

155

Ich muss unterschiedliche Logik basierend auf unterschiedlichen aktuellen Umgebungsprofilen codieren. Wie können Sie die aktuellen aktiven und Standardprofile von Spring abrufen?

Bobo
quelle
3
@aweigold: Im Frühjahr 3.1 programmgesteuert das aktuelle Aktiv / Standard-Umgebungsprofil abrufen. Welche weiteren Details benötigen Sie?
Bobo

Antworten:

74

Erweitern der netten einfachen Antwort von User1648825 (Ich kann keinen Kommentar abgeben und meine Bearbeitung wurde abgelehnt):

@Value("${spring.profiles.active}")
private String activeProfile;

Dies kann eine IllegalArgumentException auslösen, wenn keine Profile festgelegt sind (ich erhalte einen Nullwert). Dies kann eine gute Sache sein, wenn Sie es einstellen müssen; Wenn nicht, verwenden Sie die 'Standard'-Syntax für @Value, dh:

@Value("${spring.profiles.active:Unknown}")
private String activeProfile;

... activeProfile enthält jetzt 'Unbekannt', wenn spring.profiles.active nicht aufgelöst werden konnte

MartinMlima
quelle
Profilnamen werden durch ein Komma getrennt. Kasse baeldung.com/spring-profiles#2-using-springactiveprofile
Jason
56

Hier ist ein vollständigeres Beispiel.

Autowire-Umgebung

Zuerst möchten Sie die Umgebungs-Bean automatisch verdrahten.

@Autowired
private Environment environment;

Überprüfen Sie, ob Profile in aktiven Profilen vorhanden sind

Anschließend können Sie getActiveProfiles()herausfinden, ob das Profil in der Liste der aktiven Profile vorhanden ist. Hier ist ein Beispiel, das das String[]from verwendet getActiveProfiles(), einen Stream von diesem Array abruft und dann Matcher verwendet, um nach mehreren Profilen zu suchen (ohne Berücksichtigung der Groß- und Kleinschreibung), die einen Booleschen Wert zurückgeben, falls vorhanden.

//Check if Active profiles contains "local" or "test"
if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("test") 
   || env.equalsIgnoreCase("local")) )) 
{
   doSomethingForLocalOrTest();
}
//Check if Active profiles contains "prod"
else if(Arrays.stream(environment.getActiveProfiles()).anyMatch(
   env -> (env.equalsIgnoreCase("prod")) )) 
{
   doSomethingForProd();
}

Sie können ähnliche Funktionen auch mithilfe der Anmerkungsprofile erzielen, die @Profile("local")eine selektive Konfiguration basierend auf einem übergebenen oder Umgebungsparameter ermöglichen. Hier finden Sie weitere Informationen zu dieser Technik: Federprofile

anataliocs
quelle
2
@Profile scheint die beste Lösung zu sein.
Paul Waldo
Ich bin durch separate Linien für jede geschweifte Klammer geblendet. Keine Java-Codierungsstandards.
user1567291
26
@Value("${spring.profiles.active}")
private String activeProfile;

Es funktioniert und Sie müssen EnvironmentAware nicht implementieren. Aber ich kenne keine Nachteile dieses Ansatzes.

user1648825
quelle
3
Diese Zeile gibt diesen Fehler:Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "${spring.profiles.active}"
Zygimantus
Funktioniert perfekt für mich. Verwenden von Spring Boot 1.5.15.
Februar
Ich denke, wenn das Profil definiert ist, wird der Wert analysiert, andernfalls tritt die Ausnahme auf. Passt nicht in alle Situationen.
WesternGun
1
Aktives Profil könnte auch ein Array sein, beachten Sie dies bitte. Auf diese Weise können beim Hinzufügen zusätzlicher Profile unerwartete Fehler auftreten.
Alex Efimov
Der Nachteil dieses Ansatzes besteht darin, dass nicht alle Profile abgerufen werden, die Spring bei der Bewertung berücksichtigen könnte @Profile. Apps können die spring.profiles.include Eigenschaft auch verwenden und Profile während der Initialisierung mithilfe programmgesteuert festlegen ConfigurableEnvironment. Environment.getActiveProfiles()Sie erhalten die vollständige Liste der Profile, die mit einem dieser Mechanismen festgelegt wurden.
Scott Frederick
14

Wenn Sie kein Autowiring verwenden, implementieren Sie es einfach EnvironmentAware

Arnout Engelen
quelle
0

Es scheint eine gewisse Nachfrage zu bestehen, um statisch darauf zugreifen zu können.

Wie kann ich so etwas in statischen Methoden in nicht vom Frühling verwalteten Klassen erhalten? - Äther

Es ist ein Hack, aber Sie können Ihre eigene Klasse schreiben, um es aufzudecken. Sie müssen darauf achten, dass nichts aufgerufen wird, SpringContext.getEnvironment()bevor alle Beans erstellt wurden, da keine Garantie dafür besteht, wann diese Komponente instanziiert wird.

@Component
public class SpringContext
{
    private static Environment environment;

    public SpringContext(Environment environment) {
        SpringContext.environment = environment;
    }

    public static Environment getEnvironment() {
        if (environment == null) {
            throw new RuntimeException("Environment has not been set yet");
        }
        return environment;
    }
}
Michael
quelle