392
votes

I want to access values provided in application.properties, e.g.:

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

userBucket.path=${HOME}/bucket

I want to access userBucket.path in my main program in a Spring Boot application.

25

25 Answers

586
votes

You can use the @Value annotation and access the property in whichever Spring bean you're using

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

The Externalized Configuration section of the Spring Boot docs, explains all the details that you might need.

272
votes

Another way is injecting org.springframework.core.env.Environment to your bean.

@Autowired
private Environment env;
....

public void method() {
    .....  
    String path = env.getProperty("userBucket.path");
    .....
}
40
votes

@ConfigurationProperties can be used to map values from .properties( .yml also supported) to a POJO.

Consider the following Example file.

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

Now the properties value can be accessed by autowiring employeeProperties as follows.

@Autowired
private Employee employeeProperties;

public void method() {

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

}
17
votes

Currently, I know about the following three ways:

1. The @Value annotation

    @Value("${<property.name>}")
    private static final <datatype> PROPERTY_NAME;
  • In my experience there are some situations when you are not able to get the value or it is set to null. For instance, when you try to set it in a preConstruct() method or an init() method. This happens because the value injection happens after the class is fully constructed. This is why it is better to use the 3'rd option.

2. The @PropertySource annotation

@PropertySource("classpath:application.properties")

//env is an Environment variable
env.getProperty(configKey);
  • PropertySouce sets values from the property source file in an Environment variable (in your class) when the class is loaded. So you able to fetch easily afterword.
  • Accessible through System Environment variable.

3. The @ConfigurationProperties annotation.

  • This is mostly used in Spring projects to load configuration properties.

  • It initializes an entity based on property data.

  • @ConfigurationProperties identifies the property file to load.

  • @Configuration creates a bean based on configuration file variables.

    @ConfigurationProperties(prefix = "user")
      @Configuration("UserData")
      class user {
        //Property & their getter / setter
      }
    
      @Autowired
      private UserData userData;
    
      userData.getPropertyName();
12
votes

You can do it this way as well....

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

    @Autowired
    private Environment env;

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

Then wherever you want to read from application.properties, just pass the key to getConfigValue method.

@Autowired
ConfigProperties configProp;

// Read server.port from app.prop
String portNumber = configProp.getConfigValue("server.port"); 
7
votes

follow these steps. 1:- create your configuration class like below you can see

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:- when you have a configuration class then inject in the variable from a configuration where you need.

@Component
public class YourService {

    @Autowired
    private String getUserBucketPath;

    // now you have a value in getUserBucketPath varibale automatically.
}
5
votes

You can use the @Value to load variables from the application.properties if you will use this value in one place, but if you need a more centralized way to load this variables @ConfigurationProperties is a better approach.

Additionally you can load variables and cast it automatically if you need different data types to perform your validations and business logic.

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

@Value("${custom-app.enable-mocks}")
private boolean enableMocks;
4
votes

You can use @Value("${property-name}") from the application.properties if your class is annotated with @Configuration or @Component.

There's one more way I tried out was making a Utility class to read properties in the following way -

 protected PropertiesUtility () throws IOException {
    properties = new Properties();
    InputStream inputStream = 
   getClass().getClassLoader().getResourceAsStream("application.properties");
    properties.load(inputStream);
}

You can make use of static method to get the value of the key passed as the parameter.

3
votes

An application can read 3 types of value from the application.properties file.

application.properties


     my.name=kelly

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

class file

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

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

If you don't have a property in application.properties then you can use default value

        @Value("${your_name : default value}")
         private String msg; 
3
votes

@Value Spring annotation is used for injecting values into fields in Spring-manged beans, and it can be applied to the field or constructor/method parameter level.

Examples

  1. String value from the annotation to the field
    @Value("string value identifire in property file")
    private String stringValue;
  1. We can also use the @Value annotation to inject a Map property.

    First, we'll need to define the property in the {key: ‘value' } form in our properties file:

   valuesMap={key1: '1', key2: '2', key3: '3'}

Not that the values in the Map must be in single quotes.

Now inject this value from the property file as a Map:

   @Value("#{${valuesMap}}")
   private Map<String, Integer> valuesMap;

To get the value of a specific key

   @Value("#{${valuesMap}.key1}")
   private Integer valuesMapKey1;
  1. We can also use the @Value annotation to inject a List property.
   @Value("#{'${listOfValues}'.split(',')}")
   private List<String> valuesList;
2
votes

Spring-boot allows us several methods to provide externalized configurations , you can try using application.yml or yaml files instead of the property file and provide different property files setup according to different environments.

We can separate out the properties for each environment into separate yml files under separate spring profiles.Then during deployment you can use :

java -jar -Drun.profiles=SpringProfileName

to specify which spring profile to use.Note that the yml files should be name like

application-{environmentName}.yml

for them to be automatically taken up by springboot.

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

To read from the application.yml or property file :

The easiest way to read a value from the property file or yml is to use the spring @value annotation.Spring automatically loads all values from the yml to the spring environment , so we can directly use those values from the environment like :

@Component
public class MySampleBean {

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

// ...

}

Or another method that spring provides to read strongly typed beans is as follows:

YML

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

Corresponding POJO to read the 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) { ... }
    }
}

The above method works well with yml files.

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

2
votes
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"));
2
votes

You can use the @Value annotation for reading values from an application.properties/yml file.

@Value("${application.name}")
private String applicationName;
1
votes

For me, none of the above did directly work for me. What I did is the following:

Additionally to @Rodrigo Villalba Zayas answer up there I added
implements InitializingBean to the class
and implemented the method

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

So that will look like

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);
    }
}
1
votes

Best ways to get property values are using.

1. Using Value annotation

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

2. Using Enviornment bean

@Autowired
private Environment env;

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

public void display(){
  System.out.println("# Value : "+getValue);
}
1
votes

The best thing is to use @Value annotation it will automatically assign value to your object private Environment en. This will reduce your code and it will be easy to filter your files.

1
votes

There are two way,

  1. you can directly use @Value in you class
    @Value("#{'${application yml field name}'}")
    public String ymlField;

OR

  1. To make it clean you can clean @Configuration class where you can add all your @value
@Configuration
public class AppConfig {

    @Value("#{'${application yml field name}'}")
    public String ymlField;
}
1
votes

There are 2 ways to access value from application.properties file

  1. Using @Value annotation
    @Value("${property-name}")
    private data_type var_name;
  1. Using instance of Environment Class
@Autowired
private Environment environment;

//access this way in the method where it's required

data_type var_name = environment.getProperty("property-name");

you can also inject instance of environment using constructor injection or creating a bean yourself

1
votes

Tried Class PropertiesLoaderUtils ?

This approach uses no annotation of Spring boot. A traditional Class way.

example:

Resource resource = new ClassPathResource("/application.properties");
    Properties props = PropertiesLoaderUtils.loadProperties(resource);
    String url_server=props.getProperty("server_url");

Use getProperty() method to pass the key and access the value in the properties file.

1
votes

Maybe it can help others: you should inject @Autowired private Environment env; from import org.springframework.core.env.Environment;

and then use it this way : env.getProperty("yourPropertyNameInApplication.properties")

0
votes

I had this problem too. But there is very simple solution. Just declare your variable in constructor.

My example:

application.propperties:

#Session
session.timeout=15

SessionServiceImpl class:

private final int SESSION_TIMEOUT;
private final SessionRepository sessionRepository;

@Autowired
public SessionServiceImpl(@Value("${session.timeout}") int sessionTimeout,
                          SessionRepository sessionRepository) {
    this.SESSION_TIMEOUT = sessionTimeout;
    this.sessionRepository = sessionRepository;
}
0
votes

you can use @ConfigurationProperties it's simple and easy to access a value defined in application.properties

#datasource
app.datasource.first.jdbc-url=jdbc:mysql://x.x.x.x:3306/ovtools?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
app.datasource.first.username=
app.datasource.first.password=
app.datasource.first.driver-class-name=com.mysql.cj.jdbc.Driver
server.port=8686
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.database=mysql

@Slf4j
@Configuration
public class DataSourceConfig {
    @Bean(name = "tracenvDb")
    @Primary
    @ConfigurationProperties(prefix = "app.datasource.first")
    public DataSource mysqlDataSourceanomalie() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "JdbcTemplateenv")
    public JdbcTemplate jdbcTemplateanomalie(@Qualifier("tracenvDb") DataSource datasourcetracenv) {
        return new JdbcTemplate(datasourcetracenv);
    }
0
votes

to pick the values from property file, we can have a Config reader class something like ApplicationConfigReader.class Then define all the variables against properties. Refer below example,

application.properties

myapp.nationality: INDIAN
myapp.gender: Male

Below is corresponding reader class.

@Component
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "myapp") 
class AppConfigReader{
    private String nationality;
    private String gender

    //getter & setter
}

Now we can auto-wire the reader class wherever we want to access property values. e.g.

@Service
class ServiceImpl{
    @Autowired
    private AppConfigReader appConfigReader;

    //...
    //fetching values from config reader
    String nationality = appConfigReader.getNationality() ; 
    String gender = appConfigReader.getGender(); 
}
0
votes

application.yml or application.properties

config.value1: 10
config.value2: 20
config.str: This is a simle str

MyConfig class

@Configuration
@ConfigurationProperties(prefix = "config")
public class MyConfig {
    int value1;
    int value2;
    String str;

    public int getValue1() {
        return value1;
    }

    // Add the rest of getters here...      
    // Values are already mapped in this class. You can access them via getters.
}

Any class that wants to access config values

@Import(MyConfig.class)
class MyClass {
    private MyConfig myConfig;

    @Autowired
    public MyClass(MyConfig myConfig) {
        this.myConfig = myConfig;
        System.out.println( myConfig.getValue1() );
    }
}
0
votes

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