What is application.properties/application.yaml? (Applicable for both application.properties and application.yml)

SpringBoot comes with an build-in mechanism for configuring and setting the properties for the application through application.properties/application.yaml file.

Application properties also helps us run the application in different environments with environment specific properties and configurations.

How can we read the properties defined in application.properties/application.yaml in Springboot?

There are certain ways for us to read the properties from application.yaml/application.properties file, Let us discuss few of those methods in this article.

We are going to discuss 3 ways of reading the application.properties or application.yml file

  • Using Environment
  • @Value
  • @ConfigurationProperties

Project Structure:

project structure

Environment:

We can use Environment to get the properties from application.properties / application.yaml file.

What is an Environment?

  • Environment is an interface which extends PropertyResolver and models key aspects of Profiling and Properties.
  • Profiling: Environment will determine which profiles are active (if any present) and which profiles should be active by default (if any present)
  • Properties: Environment will provide the user with a convenient service interface for configuring property sources and resolving properties from them.

Our application.properties file,

name.website.data=javainfinite
name.website.information=Java Related Blog
server.port=8081

Our main class,

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootconfigurationApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootconfigurationApplication.class, args);
	}

}

Now let us create a controller and use our Environment to get the value from application.properties file,

@RestController
public class ConfigurationController {

    @Autowired
    private Environment environment;



    @GetMapping("/configure/{type}")
    public String propertiesValue(@PathVariable("type") Integer type) {
        if (type == 1) {
            return "From Environment: " + environment.getProperty("name.website.data") + " Information " + environment.getProperty("name.website.information");
        } else {
            return null;
        }
    }
}

We have autowired the Environment and with help of getProperty method we are fetching the data from properties file.

Output,

We need to use getProperty from Environment to fetch the data from properties file.

What we the property is not available in the properties file?

Consider we are trying to get a property which is not configured in the application.properties file, what will happen when we try to fetch that not available property from Environment?

Environment will return null if the the property is not configured in application.properties.

Default Value in Environment:

We can also set default value for the environment, when that specific property is not available. So that Environment will return the default value instead of null if the property is not configured.

How to set Default Value in Environment?

 environment.getProperty("name.website.data", "Not Available"); //Not available is the default value 

@Value

Now let us try to read the values from properties file using @Value annotation,

@Value is used at the field or method/constructor parameter level that indicates a default value expression for the annotated element.

Example,

package com.javainfinite.springbootconfiguration.controller;

import com.javainfinite.springbootconfiguration.configuration.ConfigurationPropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ConfigurationController {

    @Autowired
    private Environment environment;

    @Value("${name.website.data}")
    private String dataValue;

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



    @GetMapping("/configure/{type}")
    public String propertiesValue(@PathVariable("type") Integer type) {
        if (type == 1) {
            return "From Environment: " + environment.getProperty("name.website.data") + " Information " + environment.getProperty("name.website.information");
        } else if (type == 2) {
            return "From @Value: " + dataValue + " and information: " + information;
        } else {
            return null;
        }
    }
}

From the code we are trying to retrieve the value from properties using @Value and the property name mentioned in the application.properties file,

Output:

What if the property value is not configured in the application.properties file?

consider the example,

    @Value("${name.website.data1}")
    private String dataValue;

In the above we are trying to read name.website.data1, which is not configured in application.properties file. So when we start our SpringBoot Application, the application will fail to start with the below error

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configurationController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'name.website.data1' in value "${name.website.data1}"

How can we overcome this? is it possible to give default value?

    @Value("${name.website.data1: valueNotAvailable}") // valueNotAvailable is default value
    private String dataValue;

So when we give this default value, even if the property is not configured that @Value annotation will consider the default value and will start the spring boot application.

@ConfigurationProperties:

This is the third way to read the application.properties and most elegant way too.

Here we are going to create a configuration class,

package com.javainfinite.springbootconfiguration.configuration;

import org.springframework.context.annotation.Configuration;

@Configuration
@org.springframework.boot.context.properties.ConfigurationProperties("name.website") //part of our property configured name - prefix
public class ConfigurationPropertyValues {

    private String data; // suffix of our property name
    private String information; // suffix of our property name

    public void setData(String data) {
        this.data = data;
    }

    public void setInformation(String information) {
        this.information = information;
    }

    public String getData() {
        return data;
    }

    public String getInformation() {
        return information;
    }
}

We can use this class getters and setters to fetch the property value from application.properties or application.yaml file,

Lets see how to use it,

@RestController
public class ConfigurationController {

    @Autowired
    private Environment environment;

    @Value("${name.website.data1: valueNotAvailable}")
    private String dataValue;

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

    @Autowired
    private ConfigurationPropertyValues properties;

    @GetMapping("/configure/{type}")
    public String propertiesValue(@PathVariable("type") Integer type) {
        if (type == 1) {
            return "From Environment: " + environment.getProperty("name.website.data") + " Information " + environment.getProperty("name.website.information");
        } else if (type == 2) {
            return "From @Value: " + dataValue + " and information: " + information;
        } else {
            return "From configuration properties: " + properties.getData() + " and information" + properties.getInformation();
        }
    }
}

We have autowired the ConfigurationPropertyValues class and with the help of getter methods we are fetching the data from properties file.

Output:

Complete code can be downloaded here

By Sri

Leave a Reply

Your email address will not be published.