Cómo acceder a un valor definido en el archivo application.properties en Spring Boot

312

Quiero acceder a los valores proporcionados en application.properties, por ejemplo:

logging.level.org.springframework.web: DEBUG
logging.level.org.hibernate: ERROR
logging.file=${HOME}/application.log

userBucket.path=${HOME}/bucket

Quiero acceder userBucket.pathen mi programa principal en una aplicación Spring Boot.

Qasim
fuente

Respuestas:

467

Puede usar la @Valueanotación y acceder a la propiedad en cualquier Spring bean que esté usando

@Value("${userBucket.path}")
private String userBucketPath;

La sección Configuración externalizada de los documentos de Spring Boot explica todos los detalles que pueda necesitar.

Maestro-esclavo
fuente
55
como alternativa, también se pueden obtener de primavera Environmento vía@ConfigurationProperties
2015
3
Para agregar a la respuesta de @ sodik, este es un ejemplo que muestra cómo obtener el entorno stackoverflow.com/questions/28392231/…
cristi
¿Qué sucede si necesita acceder a más de 10 valores? ¿Debería seguir repitiendo su ejemplo 10 veces?
Jesse
Un enfoque sería hacerlo, pero es engorroso. Existen enfoques alternativos basados ​​en @Configurationclases, el problema se analiza bien en la siguiente publicación de blog
Master Slave, el
2
Tenga en cuenta que esto solo funciona en un @Component(o cualquiera de sus derivados, es decir @Repository, etc.)
Janac Meena
211

Otra forma es inyectando org.springframework.core.env.Environmenta su frijol.

@Autowired
private Environment env;
....

public void method() {
    .....  
    String path = env.getProperty("userBucket.path");
    .....
}
Rodrigo Villalba Zayas
fuente
66
también es útil cuando el nombre de la propiedad a la que necesita acceder cambia dinámicamente
Paulo Merson
3
¿Qué pasa si quieres buscar las propiedades? Y puedo sugerir incluir la declaración de importación para que todos puedan ver el nombre del paquete de Medio Ambiente, probablemente org.springframework.core.env.Environment
chrisinmtown
2
Tenga cuidado de no importar el entorno incorrecto. Intellij auto-importé el entorno CORBA.
Janac Meena
3
¿Por qué mi entorno es nulo?
Janac Meena
2
@JanacMeena tenía el mismo problema de la clase IntelliJ de importación automática de CORBA en lugar deorg.springframework.core.env.Environment
Rasshu
31

@ConfigurationPropertiesse puede usar para asignar valores de .properties( .ymltambién compatibles) a un POJO.

Considere el siguiente archivo de ejemplo.

.propiedades

cust.data.employee.name=Sachin
cust.data.employee.dept=Cricket

Employee.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@ConfigurationProperties(prefix = "cust.data.employee")
@Configuration("employeeProperties")
public class Employee {

    private String name;
    private String dept;

    //Getters and Setters go here
}

Ahora se puede acceder al valor de las propiedades mediante el cableado automático de la employeePropertiessiguiente manera.

@Autowired
private Employee employeeProperties;

public void method() {

   String employeeName = employeeProperties.getName();
   String employeeDept = employeeProperties.getDept();

}
JoBⅈN
fuente
1
Lo utilicé de esta manera y obtuve un retorno nulo, puse mi archivo de propiedades en src / test / resources y la clase de propiedades java (en la que se guarda el valor de las propiedades) en src / main / package / properties. ¿Qué me he estado perdiendo? gracias
Ahmad Leo Yudanto
debe guardar los archivos en src/main/resourcessi no está probando su código desde una prueba de Spring.
JoBⅈN
Lo mismo que @AhmadLeoYudanto y no hay nada que pueda hacer que cambie eso
Dimitri Kopriwa
6

Actualmente, conozco las siguientes tres formas:

1. La @Valueanotación

    @Value("${<property.name>}")
    private static final <datatype> PROPERTY_NAME;
  • En mi experiencia, hay algunas situaciones en las que no puede obtener el valor o se establece en null. Por ejemplo, cuando intenta configurarlo en un preConstruct()método o un init()método. Esto sucede porque la inyección de valor ocurre después de que la clase está completamente construida. Es por eso que es mejor usar la tercera opción.

2. La @PropertySourceanotación

<pre>@PropertySource("classpath:application.properties")

//env is an Environment variable
env.getProperty(configKey);</pre>
  • PropertySouceestablece valores del archivo fuente de la propiedad en una Environmentvariable (en su clase) cuando se carga la clase. Así que puedes buscar fácilmente el epílogo.
    • Accesible a través de la variable de entorno del sistema.

3. La @ConfigurationPropertiesanotación.

  • Esto se usa principalmente en proyectos Spring para cargar propiedades de configuración.
  • Inicializa una entidad basada en datos de propiedad.

    • @ConfigurationProperties identifica el archivo de propiedad para cargar.
    • @Configuration crea un bean basado en variables del archivo de configuración.
    @ConfigurationProperties (prefijo = "usuario")
    @Configuration ("UserData")
    usuario de clase {
      // Propiedad y su captador / definidor
    }
    
    @Autowired
    Private UserData userData;
    
    userData.getPropertyName ();
Dhwanil Patel
fuente
¿Qué sucede si se anula la ubicación predeterminada spring.config.location? ¿El # 2 todavía funciona?
bmauter
En tal caso, la prioridad entra en el lugar. Según sé, cuando configuras spring.config.location usando la línea de comandos, tiene alta prioridad, por lo que anula la existente.
Dhwanil Patel
5

Puedes hacerlo de esta manera también ...

@Component
@PropertySource("classpath:application.properties")
public class ConfigProperties {

    @Autowired
    private Environment env;

    public String getConfigValue(String configKey){
        return env.getProperty(configKey);
    }
}

Luego, donde quiera leer desde application.properties, simplemente pase la clave al método getConfigValue.

@Autowired
ConfigProperties configProp;

// Read server.port from app.prop
String portNumber = configProp.getConfigValue("server.port"); 
Lucifer
fuente
1
¿Qué es el paquete Environment?
e-info128
1
Encuéntralo aquí: org.springframework.core.env.Environment
lucifer
¿Qué sucede si se anula la ubicación predeterminada spring.config.location?
bmauter
3

Puede usar el @Valuepara cargar variables desde application.propertiessi usará este valor en un lugar, pero si necesita una forma más centralizada de cargar estas variables @ConfigurationPropertieses un mejor enfoque.

Además, puede cargar variables y emitirlas automáticamente si necesita diferentes tipos de datos para realizar sus validaciones y lógica de negocios.

application.properties
custom-app.enable-mocks = false

@Value("${custom-app.enable-mocks}")
private boolean enableMocks;
JorgeTovar
fuente
3

sigue estos pasos. 1: - crea tu clase de configuración como a continuación puedes ver

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value;

@Configuration
public class YourConfiguration{

    // passing the key which you set in application.properties
    @Value("${userBucket.path}")
    private String userBucket;

   // getting the value from that key which you set in application.properties
    @Bean
    public String getUserBucketPath() {
        return userBucket;
    }
}

2: - cuando tenga una clase de configuración, inyecte la variable desde una configuración donde la necesite.

@Component
public class YourService {

    @Autowired
    private String getUserBucketPath;

    // now you have a value in getUserBucketPath varibale automatically.
}
Fazle Subhan
fuente
1
1.Injecting a property with the @Value annotation is straightforward:
@Value( "${jdbc.url}" )
private String jdbcUrl;

2. we can obtain the value of a property using the Environment API

@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));
sai
fuente
1

Una aplicación puede leer 3 tipos de valor del archivo application.properties.

application.properties


     my.name=kelly

my.dbConnection ={connection_srting:'http://localhost:...',username:'benz',password:'pwd'}

archivo de clase

@Value("${my.name}")
private String name;

@Value("#{${my.dbConnection}}")
private Map<String,String> dbValues;

Si no tiene una propiedad en application.properties, puede usar el valor predeterminado

        @Value("${your_name : default value}")
         private String msg; 
NafazBenzema
fuente
0

Spring-boot nos permite varios métodos para proporcionar configuraciones externalizadas, puede intentar usar los archivos application.yml o yaml en lugar del archivo de propiedades y proporcionar diferentes archivos de propiedades configurados de acuerdo a diferentes entornos.

Podemos separar las propiedades de cada entorno en archivos yml separados en perfiles de resorte separados. Luego, durante la implementación, puede usar:

java -jar -Drun.profiles=SpringProfileName

para especificar qué perfil de resorte usar. Tenga en cuenta que los archivos yml deben tener un nombre como

application-{environmentName}.yml

para que sean automáticamente recogidos por springboot.

Referencia: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

Para leer desde el archivo application.yml o de propiedad:

La forma más fácil de leer un valor del archivo de propiedades o yml es usar la anotación spring @value. Spring carga automáticamente todos los valores desde el yml al entorno spring, por lo que podemos usar directamente esos valores del entorno como:

@Component
public class MySampleBean {

@Value("${name}")
private String sampleName;

// ...

}

U otro método que proporciona spring para leer frijoles fuertemente tipados es el siguiente:

YML

ymca:
    remote-address: 192.168.1.1
    security:
        username: admin

POJO correspondiente para leer el yml:

@ConfigurationProperties("ymca")
public class YmcaProperties {
    private InetAddress remoteAddress;
    private final Security security = new Security();
    public boolean isEnabled() { ... }
    public void setEnabled(boolean enabled) { ... }
    public InetAddress getRemoteAddress() { ... }
    public void setRemoteAddress(InetAddress remoteAddress) { ... }
    public Security getSecurity() { ... }
    public static class Security {
        private String username;
        private String password;
        public String getUsername() { ... }
        public void setUsername(String username) { ... }
        public String getPassword() { ... }
        public void setPassword(String password) { ... }
    }
}

El método anterior funciona bien con archivos yml.

Referencia: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Ananthapadmanabhan
fuente
0

Para mí, ninguno de los anteriores me funcionó directamente. Lo que hice es lo siguiente:

Además de @Rodrigo Villalba Zayas respondí allí agregué
implements InitializingBeana la clase
e implementé el método

@Override
public void afterPropertiesSet() {
    String path = env.getProperty("userBucket.path");
}

Entonces eso se verá como

import org.springframework.core.env.Environment;
public class xyz implements InitializingBean {

    @Autowired
    private Environment env;
    private String path;

    ....

    @Override
    public void afterPropertiesSet() {
        path = env.getProperty("userBucket.path");
    }

    public void method() {
        System.out.println("Path: " + path);
    }
}
Rapalagui
fuente
0

Se están utilizando las mejores formas de obtener valores de propiedad.

1. Usando la anotación de valor

@Value("${property.key}")
private String propertyKeyVariable;

2. Usando frijol ambiental

@Autowired
private Environment env;

public String getValue() {
    return env.getProperty("property.key");
}

public void display(){
  System.out.println("# Value : "+getValue);
}
Naresh Bhadke
fuente
0

Lo mejor es usar la @Valueanotación, asignará automáticamente valor a su objeto private Environment en. Esto reducirá su código y será fácil filtrar sus archivos.

MindFlayerA
fuente
0

Hay dos vías,

  1. puedes usar directamente @Valueen tu clase
    @Value("#{'${application yml field name}'}")
    public String ymlField;

O

  1. Para hacerlo limpio, puede limpiar la @Configurationclase donde puede agregar todos sus@value
@Configuration
public class AppConfig {

    @Value("#{'${application yml field name}'}")
    public String ymlField;
}
Rishabh Agarwal
fuente