572

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.

0

31 Answers 31

822

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.

9
  • 19
    as en alternative one can get those also from spring Environment or via @ConfigurationProperties
    – sodik
    Commented May 29, 2015 at 14:35
  • 5
    To add on top of @sodik's answer, this is an example that shows how to get the Environment stackoverflow.com/questions/28392231/…
    – cristi
    Commented May 6, 2016 at 17:59
  • What if you need to access over 10 values, Would you have to keep repeating your example 10times?
    – JayC
    Commented Dec 6, 2016 at 20:06
  • 1
    Adding this answer you can add some value if the property configuration is not found by default some value adding: @Value("${userBucket.path:~/bucket}") or empty @Value("${userBucket.path:}") Commented Nov 1, 2018 at 19:27
  • 20
    Note, this only works on a @Component (or any of its derivatives, i.e. @Repository, etc.) Commented Oct 10, 2019 at 15:20
366

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");
    .....
}
8
  • 25
    also useful when the name of the property you need to access changes dynamically Commented Jul 28, 2017 at 13:41
  • 4
    What if you want to search the properties? And may I suggest including the import statement so all can see the Environment package name, probably org.springframework.core.env.Environment Commented Mar 13, 2018 at 14:08
  • 5
    Be careful not to import the wrong Environment. I intellij auto-imported the CORBA Environment. Commented May 2, 2018 at 16:23
  • 7
    Why is my env null? Commented May 2, 2018 at 16:26
  • 3
    @JanacMeena had the same problem of the IntelliJ auto-importing CORBA's class instead of org.springframework.core.env.Environment
    – Rasshu
    Commented Sep 26, 2018 at 13:06
79

@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();

}
3
  • 2
    i used this way and got null return, i put my properties file in src/test/resources and properties java class (in which the properties value being saved) in src/main/package/properties. what i been missing? thanks Commented Nov 16, 2019 at 13:16
  • you have to save the files to src/main/resources if you are not testing your code from a Spring test.
    – J-J
    Commented Nov 17, 2019 at 8:29
  • Same as @AhmadLeoYudanto and there is nothing I can do that change that Commented Apr 2, 2020 at 9:25
42

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 third 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();
3
  • What if the default location is overridden with spring.config.location? Does #2 still work?
    – bmauter
    Commented Apr 6, 2020 at 14:18
  • In such case, priority comes into the place. As per i know when you set spring.config.location using command line it have high priority so it override existing one. Commented Apr 6, 2020 at 17:10
  • 3
    Many thanks for this >> "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."<< Commented Jun 16, 2021 at 13:00
18

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"); 
4
  • 2
    What package is Environment?
    – e-info128
    Commented Mar 21, 2019 at 19:42
  • 1
    Find it here: org.springframework.core.env.Environment
    – lucifer
    Commented Apr 1, 2019 at 6:02
  • What if the default location is overridden with spring.config.location?
    – bmauter
    Commented Apr 6, 2020 at 14:17
  • Why do you need @PropertySource when you inject Spring Environment which reads properties from application.properties file by default? Commented Jun 19, 2023 at 3:15
15

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 the getUserBucketPath
        // variable automatically.
    }
    
0
12

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.

1
  • Thanks for this, helped in case where i couldn't CDI :) Commented Jan 12, 2023 at 9:41
12

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 these variables @ConfigurationProperties is a better approach.

Additionally, you can load variables and cast them 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;
1
  • The casting is very nice. What additional is necessary as I get "Annotations not allowed here" no matter where I put it. I am missing something. Do I need a some other per-configuration to use this annotation anywhere?
    – cp.
    Commented Jul 26, 2021 at 17:00
7

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

application.properties

myapp.nationality: INDIAN
myapp.gender: Male

Below is the corresponding reader class.

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

    // Getter and 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 the configuration reader
    String nationality = appConfigReader.getNationality() ;
    String gender = appConfigReader.getGender();
}
0
7

You should inject @Autowired private Environment env; from import org.springframework.core.env.Environment;

And then use it this way:

env.getProperty("yourPropertyNameInApplication.properties")

7

There are 3 ways to read the application.properties:

1st way:

Using @Value, EnvironmentInterface and @ConfigurationProperties:

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

2nd way:

@Autowired
private Environment environment; // org.springframework.core.env.Environment;

String s = environment.getProperty("userBucket.path");

3rd way:

@ConfigurationProperties("userbucket")
public class Config {
   
    private String path;

    // getters and setters
}

Can be read with getters and setters..

Reference - here

2
  • It would be really helpful if you added the import statements for Value, Environment, ad ConfigurationProperties Commented Feb 11, 2022 at 21:55
  • Don't forget (1) the class should be annotated with something like @Component, and (2) you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:55
6

@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;
1
6

An application can read three types of values 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 the default value:

@Value("${your_name: default value}")
private String msg;
1
  • connection_srting can't be right. Commented Feb 11, 2023 at 0:57
4
  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
  • Where is setUrl defined? How come I get a compiler error. Actually I'm more interested in setPassword if possible. Thanks.
    – Louis
    Commented Aug 27, 2021 at 14:23
  • For #1 above, don't forget (1) the class should be annotated with something like @Component, and (2) you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:55
3

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

@Value("${application.name}")
private String applicationName;
2
  • 1
    form which library value you imported?
    – S Gaber
    Commented Nov 17, 2020 at 17:27
  • Don't forget (1) the class should be annotated with something like @Component, and (2) you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:55
3

There are two ways to access the value from the application.properties file:

  1. Using the @Value annotation

    @Value("${property-name}")
    private data_type var_name;
    
  2. Using an instance of the 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 an instance of the environment using constructor injection or creating a bean yourself.

3

There are actually three ways to read the application.properties file,

Using Environment,

@Autowired
Environment environment

environment.getProperty({propertyName})

Or we can use @Value,

@Value("${property}")

but the problem with @Value is it might throw an exception if the value is not in the properties file.

The suggested way is using @ConfigurationProperties

@ConfigurationProperties("userBucket")
public class test{
  private String path;
  //getters and setters
}

For a detailed example - Reading application.properties.

2

Another way to find a key/value in the configuration.

...
import org.springframework.core.env.ConfigurableEnvironment;
...
@SpringBootApplication
public class MyApplication {

    @Autowired
    private ConfigurableEnvironment  myEnv;

...
  
    @EventListener(ApplicationReadyEvent.class)
    public void doSomethingAfterStartup() 
    throws Exception {
        
        LOG.info("myEnv (userBucket.path): " + myEnv.getProperty("userBucket.path"));
    }
} 
1
  • Thanks! That's how to programmatically get property values.
    – LovaBill
    Commented May 26, 2022 at 14:24
2

You can access the application.properties file values by using:

@Value("${key_of_declared_value}")
1
  • Don't forget (1) the class should be annotated with something like @Component, and (2) you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:55
2

The best ways to get property values are using:

1. Using Value annotation

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

2. Using the Environment bean

@Autowired
private Environment env;

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

public void display() {
    System.out.println("# Value : " + getValue);
}
1
  • 1
    Don't forget (1) the class should be annotated with something like @Component, and (2) you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:55
2

Spring Boot allows us several methods to provide externalized configurations. You can try using file 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 YAML 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 YAML files should be named like

application-{environmentName}.yml

for them to be automatically taken up by Spring Boot.

Reference: 2. Externalized Configuration

To read from the application.yml or property file:

The easiest way to read a value from the property file or YAML is to use the Spring @value annotation. Spring automatically loads all values from the YAML file 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 YAML content:

@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 YAML files.

Reference: 2. Externalized Configuration

1
  • Also note.. you cannot make your member/variable static for @Value to work. Commented Feb 15, 2023 at 20:56
2

There are two ways,

  1. you can directly use @Value in your 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;
    }
    
2

Try class PropertiesLoaderUtils. This approach doesn’t use any annotation of Spring Boot. It is a traditional class way.

Example:

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

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

1

The best thing is to use the @Value annotation. It will automatically assign a value to your object private Environment en.

This will reduce your code, and it will be easy to filter your files.

0
1

You can use the @Value annotation and access the property in a Spring bean:

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

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

The easiest way would be to use the @Value annotation provided by Spring Boot. You need to define a variable at class level. For example:

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

There is another way you can do this via the Environment Class. For example:

  1. Autowire the environment variable to your class where you need to access this property:

@Autowired private Environment environment

  1. Use the environment variable to get the property value in the line you need it using:

environment.getProperty("userBucket.path");

Hope this answers your question!

0

To read application.properties or application.yml attributes follow the following steps:

  1. Add your attributes in application.properties or application.yaml
  2. Create config class and add your attributes
application.jwt.secretKey=value
application.jwt.tokenPrefix=value
application.jwt.tokenExpiresAfterDays=value ## 14
application:
  jwt:
    secret-key: value
    token-prefix: value
    token-expires-after-days: value ## 14
@Configuration("jwtProperties") // you can leave it empty
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "application.jwt") // prefix is required
public class JwtConfig {
    private String secretKey;
    private String tokenPrefix;
    private int tokenExpiresAfterDays;

    // getters and setters
}

NOTE: in .yaml file you have to use kabab-case

Now to use the config class just instantiate it, you can do this manualy or with dependency injection.

public class Target {

  private final JwtConfig jwtConfig;

  @Autowired
  public Target(JwtConfig jwtConfig) {
      this.jwtConfig = jwtConfig;
  }

  // jwtConfig.getSecretKey()

}
0

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

In addition to Rodrigo Villalba Zayas' answer, 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);
    }
}
0

I had this problem too. But there is a very simple solution. Just declare your variable in the 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;
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.