Como acessar um valor definido no arquivo application.properties no Spring Boot

312

Quero acessar os valores fornecidos em application.properties, por exemplo:

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

userBucket.path=${HOME}/bucket

Quero acessar userBucket.pathmeu programa principal em um aplicativo Spring Boot.

Qasim
fonte

Respostas:

467

Você pode usar a @Valueanotação e acessar a propriedade em qualquer bean Spring que estiver usando

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

A seção Configuração Externalizada dos documentos da Inicialização em Spring explica todos os detalhes que você pode precisar.

Senhor de escravos
fonte
5
como en uma alternativa pode obter esses também a partir da Primavera Environmentou via@ConfigurationProperties
sodik
3
Para adicionar no topo de resposta de @ sodik, este é um exemplo que mostra como obter o Meio Ambiente stackoverflow.com/questions/28392231/...
cristi
E se você precisar acessar mais de 10 valores, teria que continuar repetindo seu exemplo 10 vezes?
Jesse
uma abordagem seria fazê-lo, mas é complicado. Existem abordagens alternativas baseadas em @Configurationclasses, o problema é bem analisado na seguinte postagem
Master Slave
2
Note, isso só funciona em um @Component(ou qualquer de seus derivados, ie @Repository, etc.)
Janac Meena
211

Outra maneira é injetar org.springframework.core.env.Environmentno seu feijão.

@Autowired
private Environment env;
....

public void method() {
    .....  
    String path = env.getProperty("userBucket.path");
    .....
}
Rodrigo Villalba Zayas
fonte
6
Também útil quando o nome da propriedade que você precisa para o acesso muda dinamicamente
Paulo Merson
3
E se você quiser pesquisar as propriedades? E posso sugerir incluindo a declaração de importação para que todos possam ver o nome do pacote Ambiente, provavelmente org.springframework.core.env.Environment
chrisinmtown
2
Cuidado para não importar o ambiente errado. Importei automaticamente o ambiente CORBA.
Janac Meena
3
Por que meu env é nulo?
Janac Meena
2
O @JanacMeena teve o mesmo problema da classe do CORBA de importação automática do IntelliJ em vez deorg.springframework.core.env.Environment
Rasshu
31

@ConfigurationPropertiespode ser usado para mapear valores de .properties( .ymltambém suportado) para um POJO.

Considere o seguinte arquivo de exemplo.

.properties

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
}

Agora, o valor das propriedades pode ser acessado através da ligação automática da employeePropertiesseguinte maneira.

@Autowired
private Employee employeeProperties;

public void method() {

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

}
JoBⅈN
fonte
1
Eu usei dessa maneira e obtive retorno nulo, coloquei meu arquivo de propriedades na classe java src / test / resources e properties (na qual o valor das propriedades está sendo salvo) em src / main / package / properties. o que eu estava perdendo? obrigado
Ahmad Leo Yudanto
você deve salvar os arquivos src/main/resourcesse não estiver testando seu código em um teste do Spring.
JoBⅈN 17/11/19
Mesmo que @AhmadLeoYudanto e não há nada que eu possa fazer que mude isso
Dimitri Kopriwa
6

Atualmente, conheço as três maneiras a seguir:

1. A @Valueanotação

    @Value("${<property.name>}")
    private static final <datatype> PROPERTY_NAME;
  • Na minha experiência, existem algumas situações em que você não consegue obter o valor ou ele está definido como null. Por exemplo, quando você tenta defini-lo em um preConstruct()método ou init()método. Isso acontece porque a injeção de valor ocorre depois que a classe é totalmente construída. É por isso que é melhor usar a 3ª opção.

2. A @PropertySourceanotação

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

//env is an Environment variable
env.getProperty(configKey);</pre>
  • PropertySoucedefine valores do arquivo de origem da propriedade em uma Environmentvariável (na sua classe) quando a classe é carregada. Então você é capaz de buscar facilmente um posfácio.
    • Acessível através da variável de ambiente do sistema.

3. A @ConfigurationPropertiesanotação.

  • Isso é usado principalmente em projetos Spring para carregar propriedades de configuração.
  • Inicializa uma entidade com base nos dados da propriedade.

    • @ConfigurationProperties identifica o arquivo de propriedades a ser carregado.
    • @Configuration cria um bean com base nas variáveis ​​do arquivo de configuração.
    @ConfigurationProperties (prefixo = "usuário")
    @Configuration ("UserData")
    usuário da classe {
      // Propriedade e seu getter / setter
    }
    
    @Autowired
    private UserData userData;
    
    userData.getPropertyName ();
Dhwanil Patel
fonte
E se o local padrão for substituído spring.config.location? # 2 ainda funciona?
bmauter 6/04
Nesse caso, a prioridade entra em cena. Como eu sei quando você define spring.config.location usando a linha de comando, ela tem alta prioridade e substitui a existente.
Dhwanil Patel 06/04
5

Você pode fazê-lo dessa maneira também ....

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

    @Autowired
    private Environment env;

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

Onde quer que você queira ler a partir de application.properties, basta passar a chave para o método getConfigValue.

@Autowired
ConfigProperties configProp;

// Read server.port from app.prop
String portNumber = configProp.getConfigValue("server.port"); 
Lúcifer
fonte
1
Que pacote é Environment?
precisa saber é o seguinte
1
Encontre-o aqui: org.springframework.core.env.Environment
lucifer
E se o local padrão for substituído spring.config.location?
bmauter 6/04
3

Você pode usar o @Valuepara carregar variáveis ​​do application.propertiesse você usar esse valor em um único local, mas se precisar de uma maneira mais centralizada de carregar essas variáveis, @ConfigurationPropertiesé uma abordagem melhor.

Além disso, você pode carregar variáveis ​​e convertê-las automaticamente se precisar de tipos de dados diferentes para executar suas validações e lógica de negócios.

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

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

Siga esses passos. 1: - crie sua classe de configuração como abaixo, você pode 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: - quando você tem uma classe de configuração, injete a variável na configuração em que você precisa.

@Component
public class YourService {

    @Autowired
    private String getUserBucketPath;

    // now you have a value in getUserBucketPath varibale automatically.
}
Fazle Subhan
fonte
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
fonte
1

Um aplicativo pode ler 3 tipos de valor no arquivo application.properties.

application.properties


     my.name=kelly

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

arquivo de classe

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

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

Se você não tiver uma propriedade em application.properties, poderá usar o valor padrão

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

O Spring-boot nos permite vários métodos para fornecer configurações externalizadas, você pode tentar usar arquivos application.yml ou yaml em vez do arquivo de propriedades e fornecer diferentes arquivos de propriedades configurados de acordo com diferentes ambientes.

Podemos separar as propriedades de cada ambiente em arquivos yml separados em perfis de mola separados.Em seguida, durante a implantação, você pode usar:

java -jar -Drun.profiles=SpringProfileName

para especificar qual perfil de primavera usar. Observe que os arquivos yml devem ter nomes como

application-{environmentName}.yml

para que sejam capturados automaticamente pelo springboot.

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

Para ler do arquivo application.yml ou property:

A maneira mais fácil de ler um valor do arquivo de propriedades ou do yml é usar a anotação spring @value.Spring carrega automaticamente todos os valores do yml para o ambiente do spring, para que possamos usar diretamente esses valores do ambiente, como:

@Component
public class MySampleBean {

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

// ...

}

Ou outro método que o Spring fornece para ler feijões fortemente tipados é o seguinte:

YML

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

POJO correspondente para ler o 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) { ... }
    }
}

O método acima funciona bem com arquivos yml.

Referência: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Ananthapadmanabhan
fonte
0

Para mim, nenhuma das opções acima funcionou diretamente para mim. O que eu fiz é o seguinte:

Além da resposta do @Rodrigo Villalba Zayas, adicionei
implements InitializingBeanà classe
e implementei o método

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

Então isso vai parecer

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

As melhores maneiras de obter valores de propriedade estão usando.

1. Usando anotação de valor

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

2. Usando o bean Enviornment

@Autowired
private Environment env;

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

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

O melhor é usar a @Valueanotação que atribuirá valor automaticamente ao seu objeto private Environment en. Isso reduzirá seu código e será fácil filtrar seus arquivos.

MindFlayerA
fonte
0

Há duas vias,

  1. você pode usar diretamente @Valuena sua classe
    @Value("#{'${application yml field name}'}")
    public String ymlField;

OU

  1. Para torná-lo limpo, você pode limpar a @Configurationclasse onde você pode adicionar todos os seus@value
@Configuration
public class AppConfig {

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