If you are a Spring Boot developer, you must have come across the โapplication.propertiesโ or โapplication.ymlโ file. Needless to say, these files reduces your development effort by minimizing the amount of XMLs that you were writing in a standard Spring based project. Moreover, we accommodate the common properties of our project in the form of key-value pairs in these files. Therefore, it becomes more than important to know all about these files. These are application properties file with the extension of either โ.propertiesโ or โ.ymlโ. Hence, our topic for this article is โHow to Write Spring Boot Application Properties Filesโ.
Furthermore, Spring Boot already provides some of the ready-made keys that we use most of the times in our project. Sometimes, we need to create custom properties files in order to fulfil the business requirements. So, we will discuss all about them in this article step by step. Additionally, if you are going to appear in any Spring Boot interview, you are expected to get at least one question from this article. Letโs go through our article โHow to Write Spring Boot Application Properties Filesโ and its related concepts step by step.
Table of Contents (Click on links below to navigate)
- 1 What is application.properties in Spring Boot?
- 2 What types of keys does an application.properties contain?
- 3 What are the valid locations of Properties files in the Project? How to load them?
- 4 How to read keys of the properties file into the application?
- 5 How to write Custom Properties file in Spring Boot?
- 6 How can we create and load multiple properties files in the application?
- 7 How to map multiple properties with a single variable? When to use @ConfigurationProperties annotation?
- 8 What are the general guidelines/rules to use @ConfigurationProperties annotation?
- 9 Example: How to read multiple values from the properties file in our code?
- 10 How to read multiple values from the properties file in our code as a Collection?
- 11 Example
- 12 How to read multiple values from the properties file in our code as an Object?
- 13 What is YAML(.yml) file?ย
- 14 What are the rules/guidelines to write a YAML(.yml) file?
- 15 How to convert into YAML(.yml) file from a .properties file?
- 16 Example: Converting .properties into .yml
- 17 FAQ
What is application.properties in Spring Boot?
In a Spring Boot Application, โapplication.propertiesโ is an input file to set the application up. Unlike the standard Spring framework configuration, this file is auto detected in a Spring Boot Application. It is placed inside โsrc/main/resourcesโ directory. Therefore, we donโt need to specially register a PropertySource, or even provide a path to a property file.
An application.properties file stores various properties in key=value format. These properties are used to provide input to Spring container object, which behaves like one time input or static data.
What types of keys does an application.properties contain?
An application.properties file contains two types of keys : pre-defined keys, and programmer defined keys.
Pre-defined Keys
Spring framework provides several common default properties to specify inside application.properties such as to support database, email, JPA, Hibernate,ย Logging, AOP etc. We can find the list of Common Application Properties from Spring Official Documentation.
However, we donโt need to define all the default properties every time. We can define what are required for our application at present. This is also a benefit of using Spring Boot where it reduces XML based configurations and customize them to simple properties.
Programmer-defined Keys
A programmer can also define project specific keys whenever required. We will discuss about how to define them in the following sections of this article.
What are the valid locations of Properties files in the Project? How to load them?
Generally, there are two valid locations for Properties file:
1) src/main/resource (classpath:)
Syntax for this is: @PropertySource(โclasspath:application.propertiesโ)
2) Inside project folder ( file:/)
Syntax for this is:@PropertySource(โfile:/application.propertiesโ)
How to read keys of the properties file into the application?
In order to read values from keys, we have two ways:
Using @Value
This annotation is provided by the Spring Framework .To read one key from the properties file, we need to declare one variable in our class. Moreover, we need to apply the @Value annotation at the variable with the key as a parameter to it. Itโs like @Value(โ${key}โ)
โฅ At a time we can read one key value into one variable. For example, if we have 10 keys, then we should write @Value on top of 10 variables.
โฅ If the key is not present in the properties file and we try to read using @Value() then it will throw an Exception:
IllegalArgumentException: Could not resolve placeholder โmy.app.idโ in value โ${my.app.id}โ
Using @ConfigurationProperties
This is provided by Spring Boot. We will discuss about in detail in the subsequent sections.
How does the @Value work internally in Spring?
First โapplication.propertiesโ file is loaded using code like @PropertySource(โclasspath:application.propertiesโ). Now, Spring container creates one MEMORY โEnvironmentโ (key-val pairs) that holds all the key-vals given by Properties file. We can read those values into variable using Syntax
@Value(โ${key}โ).ย Then, @Value will search for key in Environment memory. If found then value is updated into container object.
How to write Custom Properties file in Spring Boot?
There are some certain steps to write our own properties file. Letโs follow below steps:
Step#1:ย Define your properties file with any name with extension .properties
Right click on โsrc/main/resourcesโ > new > file > Enter name : product.properties
Additionally, Enter content as applicable. For example,
-----product.properties------ product.title=my product product.version=2.5
Step#2: At Main class/Starter class, apply @PropertySource annotation
In our case, the Syntax will be: @PropertySource(โclasspath:product.propertiesโ)
Example:ย
For Example, letโs assume we are going to define a โproduct.propertiesโ
Step #1: Create a Spring Boot Project
Here, we will use STS(Spring Tool Suite) to create our Spring Boot Project. If you are new to Spring Boot, visitย Internal Link to create a sample project in spring boot.
Step#2: Create a new properties file under src/main/resources folder
Letโs name it product.properties.
product.title=my product product.version=2.5
Step#3: Create a class to read values from properties file
In order to read values from properties file, letโs create a class Product.java as below. Donโt forget to apply @Component annotation.
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Product { @Value("${product.title}") private String title; @Value("${product.version}") private Double version; @Override public String toString() { return "Product [title=" + title + ", version=" + version + "]"; } }
Step#4: Apply @PropertySource(โโโ) at the main/starter class
In main or starter class whichever is applicable in your case, apply @PropertySource(โclasspath:product.propertiesโ) in order to tell Spring Container that you are using a custom properties file as below. Moreover, we need to print the product class to check the values.
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.PropertySource; @SpringBootApplication @PropertySource("classpath:product.properties") public class SpringBootPropertiesApplication { public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(SpringBootPropertiesApplication.class, args); Product product= applicationContext.getBean("product", Product.class); System.out.println(product); } }
Step#4: Test the output
Right click on the project, Run As > Spring Boot App. Now check the output at console. You will see the below output.
Product [title=my product, version=2.5]
How can we create and load multiple properties files in the application?
It is absolutely possible to create & load multiple properties files in the application with the help of @PropertySource itself. Below is the syntax to use it in case of multiple properties.
@PropertySource({ "classpath:abc.properties", "classpath:pqr.properties", "classpath:xyz.properties", "....", "...." })
If we define the same key with different values in different properties files, which one will be selected?
In this case, the last loaded properties file key will be considered.
For example, consider the below properties file declaration.
@PropertySource({
โclasspath : abc.propertiesโ,ย ย ย //ย loading order 1st
โclasspath : xyz. propertiesโย ย //ย ย loading order 2nd
})
From the above example, first it will check in โabc.propertiesโ for the given key, if the key also exists in โxyz.propertiesโ, the values will be reflected from โxyz.propertiesโ, as it is loaded at the last.
โฆ if it doesnโt exist in both the files, priority is for โapplication.propertiesโ.
How to map multiple properties with a single variable? When to use @ConfigurationProperties annotation?
As aforementioned, we can use @Value annotation to read only one property from the properties file at a time into our code. Spring core framework provides this feature. Suppose we have a requirement where we need to read multiple properties from properties file in our code. Here, we will make use of @ConfigurationProperties annotation. Furthermore, @ConfigurationProperties also supports working with Collections and Bean Type (class Type). Actually, we will have this kind of scenario multiple times in our project. Letโs be aware that Spring Boot provides the @ConfigurationProperties annotation.
What are the general guidelines/rules to use @ConfigurationProperties annotation?
1) The prefix provided inside the @ConfigurationProperties annotation must match with the prefix given in the properties file, else variable will not get the correct values.
2) We must generate getters and setters for the variables that we used to map with the keys of properties file.
โฅ Note: Since @Value uses refection based data read, hence getters & setters are not required in that case.
โฅ Note: While applying @ConfigurationProperties annotation, you may get a warning โWhen using @ConfigurationProperties it is recommended to use โspring-boot-configuration-processorโ to your classpath to generate configuration metadataโ. You can resolve it by clicking on the warning and selecting โAdd to spring-boot-configuration-processor pom.xmlโ as shown below in the screenshot. Alternative way to resolve it is that you can manually add the dependency ofย โspring-boot-configuration-processorโ in your pom.xml file.
Example: How to read multiple values from the properties file in our code?
Letโs develop an example of reading multiple values from the properties file in our code. However, in this example we will consider the simplest case. Further, in the subsequent sections, we will cover the complex scenarios.
Step#1: Update the application.properties fileย
For example, letโs consider below values. Here, each entry is in the form of โprefix.variable=valueโ. Obviously, โprefix.variableโ forms the key. Therefore, the last word of the key becomes the variable in our class. On the other hand, the remaining left side part becomes the prefix, which in turn becomes the parameter of @ConfigurationProperties annotation.
product.app.id=1024 product.app.code=QS5329D product.app.version=3.34
Step#2: Create a Runner class and define variables
Letโs create a class and define variables. Here we are taking a Runner class just to test the example easily. Also, letโs follow below guidelines.
1) Apply annotation @ConfigurationProperties(โproduct.appโ) on top of the class. Make sure that prefix as a parameter of this annotation must match with the prefix given in the keys of the properties file. In our case, โproduct.appโ is the prefix.
2) After prefix we have id, code & version respectively in the keys. Hence, these parts of the keys will become the variable names in our class as below.
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("product.app") @PropertySource("classpath:product.properties") public class ProductDataReader implements CommandLineRunner { private Integer id; private String code; private Double version; @Override public void run(String... args) throws Exception { System.out.println(this); } @Override public String toString() { return "ProductDataReader [id=" + id + ", code=" + code + ", version=" + version + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Double getVersion() { return version; } public void setVersion(Double version) { this.version = version; } }
However, in this example, we have applied @PropertySource(โclasspath:product.propertiesโ) in Runner class. We can also apply it at the main class optionally.
Step#3: Check the Output
Now, run the application and check the output. It will be like below.
ProductDataReader [id=1024, code=QS5329D, version=3.34]
How to read multiple values from the properties file in our code as a Collection?
We need to follow some guidelines in order to read values from properties file in the form of a Collection in our code. Every developer knows how to define a collection variable in the class. But how can we define the respective values in the properties file is the point of discussion here. Letโs discuss it step by step as below.
List/Set/Arrayย
In case of List, Set and Array, we should use index that starts with zero as below.
prefix.variable[index]=value
For example: product.app.info[0]=InfoValue1,ย product.app.info[1]=InfoValue2, โฆ..and so on.
Map/Properties
Letโs understand a basic difference between Map & Properties first. Map (Interface) Generics Types are provided by Programmer and having multiple Implementations. Properties is a class that stores data with single format key=val (by default converted as String). Here, Map & Properties takes the same format key=value as shown below.
prefix.variable.key=value
For example: product.app.category.C1=CategoryValue1, product.app.category.C2=CategoryValue2, โฆ..and so on.
Example
Step#1: Update the application.properties fileย
Letโs update the product.properties file as per the guidelines given above.
product.app.info[0]=InfoValue1 product.app.info[1]=InfoValue2 product.app.info[2]=InfoValue3 product.app.category.C1=CategoryValue1 product.app.category.C2=CategoryValue2
Step#2: Create a Runner class and define variables
As we have already discussed why we are using a Runner class here, letโs jump to the example directly as below.
import java.util.List; import java.util.Map; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("product.app") @PropertySource("classpath:product.properties") public class ProductDataReader implements CommandLineRunner { private List<String> info; //private Set<String> info; //private String[] info; ย ย private Map<String,String> category; //private Properties category; @Override public void run(String... args) throws Exception { System.out.println(this); } public List<String> getInfo() { return info; } public void setInfo(List<String> info) { this.info = info; } public Map<String, String> getCategory() { return category; } public void setCategory(Map<String, String> category) { this.category = category; } @Override public String toString() { return "ProductDataReader [info=" + info + ", category=" + category + "]"; } }
Step#3: Check the Output
Now, run the application and check the output. It will be like below.
ProductDataReader [info=[InfoValue1, InfoValue2, InfoValue3], category={C2=CategoryValue2, C1=CategoryValue1}]
How to read multiple values from the properties file in our code as an Object?
Instead of being a Collection type, suppose our variable is an instance of a particular type. In this case also, we need to follow some guidelines in order to read values from properties file. Letโs discuss it step by step as below.
We can even read properties data into one class object by using HAS-A relation and syntax is as below:
prefix.objectName.variable=valueย ย ย ORย ย ย ย prefix.hasAVariable.variable=value
Step#1: Update the application.properties fileย
Letโs update the product.properties file as per the guidelines given above.
product.app.brand.name=brandName product.app.brand.price=4569.75
Step#2: Create a model class and define its propertiesย
In order to make a variable of a particular type(Class type), letโs create a model class & define some properties. To illustrate, letโs assume that we have a Brand of the Product. Therefore, we will create a Brand class as step by step as below.
1)ย Create one class with variables(properties)
2)ย Generate getters, setters, toString.
3)ย Use this class as Data Type and create HAS-A variable(reference variable) in other class.
Note:ย Do not apply @Component over this class type. This object is created only on condition: โIf data exists in properties fileโ. This work is taken care by the annotation @ConfigurationProperties.
public class Brand { private String name; private Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } @Override public String toString() { return "Brand [name=" + name + ", price=" + price + "]"; } }
Step#3: Create a Runner class and define variables
As we have already discussed why we are using a Runner class here, letโs jump to the example directly as below.
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("product.app") @PropertySource("classpath:product.properties") public class ProductDataReader implements CommandLineRunner { private Brand brand; //HAS-A @Override public void run(String... args) throws Exception { System.out.println(this); } public Brand getBrand() { return brand; } public void setBrand(Brand brand) { this.brand = brand; } @Override public String toString() { return "ProductDataReader [brand=" + brand + "]"; } }
Step#4: Check the Output
Now, run the application and check the output. It will be like below.
ProductDataReader [brand=Brand [name=brandName, price=4569.75]]
What is YAML(.yml) file?ย
YAML is a latest format to define key:val pairs without having duplicate words in more than one key. In other words, YAML is a convenient format for specifying hierarchical configuration data. It uses โSnake YAMLโ API and it is added by default in every Spring Boot Application. Moreover, it has following benefits for the developer.
1) It has a good look and feel and even easy to read.
2)ย No duplicate words in levels/keys.
3)ย Auto-Parsing supported using Snake-YAML API.
4)ย Also, easy to write.
What are the rules/guidelines to write a YAML(.yml) file?
1) Unlike .properties file, dot(.) and equals(=) are not allowed, but only colon(:) is allowed.
2) Before each value in .yml file, we must provide exactly one blank space.
3) After every colon(:) symbols, go to new line/change line and provide spaces, if key is still incomplete.
4) Spaces count/indentation/alignment must be matching for the same level of key.
5) Do not provide any duplicate levels/hierarchy.
How to convert into YAML(.yml) file from a .properties file?
Generally, there are two ways to convert a .properties file into a .yml file: 1) Manuallyย 2) With the help of IDE like STS.
Manually
1) Replace all occurrences of dot(.) and equals(=) with colon(:)
2) Follow rules/guidelines given in the above section.
If your file has lengthy content, it will take too much effort to convert.
Using STS
If you are using an IDE like STS(Spring Tool Suite), you can perform conversion in a single click as below.
Right click on .properties file and select option: Convert .properties to .yamlโ and finally click on โOKโ. You will get a .yml file in less than a minute.
Example: Converting .properties into .yml
For example, Letโs convert our โproduct.propertiesโ into โproduct.ymlโ.
product.properties
product.app.id=1024 product.app.code=QS5329D product.app.version=3.34 product.app.info[0]=InfoValue1 product.app.info[1]=InfoValue2 product.app.info[2]=InfoValue3 product.app.category.C1=CategoryValue1 product.app.category.C2=CategoryValue2 product.app.brand.name=brandName product.app.brand.price=4569.75
Apply any one of the method of conversion given in above section. Your final โproduct.ymlโ file will look like below.
product.yml
product: app: brand: name: brandName price: 4569.75 category: C1: CategoryValue1 C2: CategoryValue2 code: QS5329D id: 1024 info: - InfoValue1 - InfoValue2 - InfoValue3 version: 3.34
FAQ
Can we modify/rename file name application.propertiesย in Spring Boot?
Yes we can, but it is not loaded by Spring Boot by default. By default, Spring Boot checks โapplication.propertiesโ under location โsrc/main/resourcesโ. If we want to load other files, follow below steps:
1)ย Create your custom file at the same location (โsrc/main/resourcesโ)
2) Apply @PropertySource annotation at starter/runner class and provide the name of your custom file as a parameter to it.
For example: @PropertySource(โclasspath:xyz.propertiesโ)
here, the classpath is โsrc/main/resourceโ folder
Alternatively, we can also keep this file inside project folder (file:/ = project folder)
If a key is present in both application.properties and our custom properties file, then which one will be selected?
Key from โapplication.propertiesโ will always have a higher priority.