1. Overview

A common practice in Spring Boot is using an external configuration to define our properties. This allows us to use the same application code in different environments.

We can use properties files, YAML files, environment variables, and command-line arguments.

In this short tutorial, we'll explore the main differences between properties and YAML files.

2. Properties Configuration

By default, Spring Boot can access configurations set in an application.properties file, which uses a key-value format:

spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
spring.datasource.password=password

Here, each line is a single configuration. Therefore, we must express hierarchical data by using the same prefixes for our keys. And, in this example, every key belongs to spring.datasource.

2.1. Placeholders in Properties

Within our values, we can use placeholders with the ${} syntax to refer to the contents of other keys, system properties, or environment variables.

app.name=MyApp
app.description=${app.name} is a Spring Boot application

2.2. List Structure

If we have the same kind of properties with different values, we can represent the list structure with array indices:

application.servers[0].ip=127.0.0.1
application.servers[0].path=/path1
application.servers[1].ip=127.0.0.2
application.servers[1].path=/path2
application.servers[2].ip=127.0.0.3
application.servers[2].path=/path3

2.3. Multiple Profiles

Since version 2.4.0, Spring Boot supports creating multi-document properties files. Simply put, we can split a single physical file into multiple logical documents.

This allows us to define a document for each profile we need to declare, all in the same file:

logging.file.name=myapplication.log
bael.property=defaultValue
#---
spring.config.activate.on-profile=dev
spring.datasource.password=password
spring.datasource.url=jdbc:h2:dev
spring.datasource.username=SA
bael.property=devValue
#---
spring.config.activate.on-profile=prod
spring.datasource.password=password
spring.datasource.url=jdbc:h2:prod
spring.datasource.username=prodUser
bael.property=prodValue

Note we use the ‘#---' notation to indicate where we want to split the document.

In this example, we have two spring sections with different profiles tagged. Also, we can have a common set of properties at the root level — in this case, the logging.file.name property will be the same in all profiles.

2.4. Profiles Across Multiple Files

As an alternative to having different profiles in the same file, we can store multiple profiles across different files. Prior to version 2.4.0, this was the only method available for properties files.

We achieve this by putting the name of the profile in the file name — for example, application-dev.yml or application-dev.properties.

3. YAML Configuration

3.1. YAML Format

As well as Java properties files, we can also use YAML based configuration files in our Spring Boot application. YAML is a convenient format for specifying hierarchical configuration data.

Now, let's take the same example from our properties file and convert it to YAML:

spring:
    datasource:
        password: password
        url: jdbc:h2:dev
        username: SA

This can be more readable than its property file alternative as it does not contain repeated prefixes.

3.2. List Structure

YAML has a more concise format for expressing lists:

application:
    servers:
    -   ip: '127.0.0.1'
        path: '/path1'
    -   ip: '127.0.0.2'
        path: '/path2'
    -   ip: '127.0.0.3'
        path: '/path3'

3.3. Multiple Profiles

Unlike properties files, YAML supports multi-document files by design, thus we can store multiple profiles in the same file no matter which version of Spring Boot we use.

In this case, however, the spec indicates we have to use three dashes to indicate the start of a new document:

logging:
  file:
    name: myapplication.log
---
spring:
  config:
    activate:
      on-profile: staging
  datasource:
    password: 'password'
    url: jdbc:h2:staging
    username: SA
bael:
  property: stagingValue

Note: we usually don't want to include both the standard application.properties and the application.yml files in our project at the same time, as it could lead to unexpected results.

For instance, if we combine the properties shown above (in an application.yml file) with the properties described in section 2.3, then bael.property would be assigned with defaultValue instead of with the profile-specific value. This is simply because the application.properties are loaded later on, overriding the values assigned up to that point.

4. Spring Boot Usage

Now that we've defined our configurations let's see how to access them.

4.1. Value Annotation

We can inject the values of our properties using the @Value annotation:

@Value("${key.something}")
private String injectedProperty;

Here, the property key.something is injected via field injection into one of our objects.

4.2. Environment Abstraction

We can also obtain the value of a property using the Environment API:

@Autowired
private Environment env;

public String getSomeKey(){
    return env.getProperty("key.something");
}

4.3. ConfigurationProperties Annotation

Finally, we can also use the @ConfigurationProperties annotation to bind our properties to type-safe structured objects:

@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
    String name;
    String description;
...

5. Conclusion

In this article, we've seen some differences between properties and yml Spring Boot configuration files. We also saw how their values could refer to other properties. Finally, we looked at how to inject the values into our runtime.

As always, all the code examples are available over on GitHub.

Generic bottom

To help you get access to the material during the current, global COVID-19 crisis, all courses are 30% off until July 2

>> GET ACCESS NOW

2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!