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
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
A bonus of using YAML is that it can store multiple profiles in the same file. And, in YAML, three dashes indicate the start of a new document. So, all the profiles can be described in the same file:
logging
file:
name: myapplication.log
spring:
profiles: staging
datasource:
password: ''
url: jdbc:h2:staging
username: SA
---
spring:
profiles: integration
datasource:
password: 'password'
url: jdbc:mysql://localhost:3306/db_integration
username: user
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.
3.4. Profiles Across Multiple Files
As an alternative to having different profiles in the same file, we can store multiple profiles across different files. And, this is the only method available when using 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.
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.