¿Cómo se obtiene el perfil de entorno activo / predeterminado actual mediante programación en Spring?

155

Necesito codificar diferentes lógicas basadas en diferentes perfiles de entorno actuales. ¿Cómo puede obtener los perfiles activos y predeterminados actuales de Spring?

Bobo
fuente
3
@aweigold: obtener el perfil de entorno actual activo / predeterminado mediante programación en la primavera 3.1. ¿Qué más detalles necesitas?
Bobo

Respuestas:

75

Ampliando la respuesta simple y agradable de User1648825 (no puedo comentar y mi edición fue rechazada):

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

Esto puede arrojar una IllegalArgumentException si no se establecen perfiles (obtengo un valor nulo). Esto puede ser algo bueno si necesita que se configure; si no, use la sintaxis 'predeterminada' para @Value, es decir:

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

... activeProfile ahora contiene 'Desconocido' si spring.profiles.active no se pudo resolver

MartinMlima
fuente
Los nombres de perfil están separados por una coma. Checkout baeldung.com/spring-profiles#2-using-springactiveprofile
Jason
56

Aquí hay un ejemplo más completo.

Entorno de cableado automático

Primero querrá conectar automáticamente el bean de entorno.

@Autowired
private Environment environment;

Comprobar si existen perfiles en perfiles activos

Luego puede usar getActiveProfiles()para averiguar si el perfil existe en la lista de perfiles activos. Aquí hay un ejemplo que toma el String[]de getActiveProfiles(), obtiene una secuencia de esa matriz y luego usa los comparadores para verificar si hay varios perfiles (mayúsculas y minúsculas) que devuelve un valor booleano si existen.

//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();
}

También puede lograr una funcionalidad similar utilizando la anotación Los @Profile("local")perfiles permiten una configuración selectiva basada en un parámetro de entorno o pasado. Aquí hay más información sobre esta técnica: Spring Profiles

anataliocs
fuente
2
@Profile parece ser la mejor solución.
Paul Waldo
Estoy cegado por líneas separadas para todas y cada una de las llaves. No estándares de codificación Java.
user1567291
26
@Value("${spring.profiles.active}")
private String activeProfile;

Funciona y no necesita implementar EnvironmentAware. Pero no conozco los inconvenientes de este enfoque.

usuario1648825
fuente
3
Esta línea da este error:Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "${spring.profiles.active}"
zygimantus
Funciona perfectamente para mi. Usando Spring Boot 1.5.15.
Febrero
Creo que si se define el perfil, se analizará el valor, de lo contrario se presenta la excepción. No se ajusta a todas las situaciones.
WesternGun
1
El perfil activo también podría ser una matriz, preste atención a eso por favor. Al usarlo, puede obtener un error inesperado al agregar perfiles adicionales.
Alex Efimov
El inconveniente de este enfoque es que no obtendrá todos los perfiles que Spring podría considerar al evaluar @Profile. Las aplicaciones también pueden usar la spring.profiles.include propiedad y pueden establecer perfiles mediante programación durante la inicialización usando ConfigurableEnvironment. Environment.getActiveProfiles()obtendrá la lista completa de perfiles configurados con cualquiera de estos mecanismos.
Scott Frederick
14

Si no está utilizando el cableado automático, simplemente implemente EnvironmentAware

Arnout Engelen
fuente
0

Parece que hay una cierta demanda para poder acceder a esto estáticamente.

¿Cómo puedo obtener tal cosa en métodos estáticos en clases no administradas por Spring? - Aetherus

Es un truco, pero puedes escribir tu propia clase para exponerlo. Debe tener cuidado para asegurarse de que nada llame SpringContext.getEnvironment()antes de que se hayan creado todos los beans, ya que no hay garantía de cuándo se instanciará este componente.

@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;
    }
}
Miguel
fuente