This tutorial covers three distinct methods for reading application properties in a Spring Boot application. These methods include:
- Using the Environment object.
- Using the @ConfigurationProperties annotation.
- Using the @Value annotation.
I made a simple Spring Boot Web App to show you how to read application properties. You can use the tutorial Create a Simple Web Service Project with Spring Boot to learn how to make a simple Web App with Spring Boot.
What is application.properties?
application.properties
is a configuration file in Spring Boot applications that stores key-value pairs of properties. These properties are used to configure various aspects of the application such as the server port, database connection, logging configuration, etc.
Spring Boot uses the Spring Framework’s Environment
abstraction to read these properties and make them available to the application. By default, application.properties
is located in the src/main/resources
directory of the application and is loaded automatically by Spring Boot. But if for any reason, you can’t find this file there, you can create it manually.
Here’s an example of how to define properties in application.properties
:
server.port=8080 spring.datasource.url=jdbc:mysql://localhost/mydb spring.datasource.username=myuser spring.datasource.password=mypassword logging.level.root=info logging.level.org.springframework=debug
In the above application.properties
file, each property is defined using the key=value
syntax, where the key is separated from the value using an equals sign.
Purpose of application.properties
The purpose of application.properties
is to provide a centralized location for configuring various aspects of a Spring Boot application. It allows developers to externalize configuration from the application code, making it easier to modify or override configuration without having to recompile the application.
In addition, application.properties
makes it easy to share configuration across multiple environments, such as development, testing, and production. By using different sets of properties for each environment, developers can ensure that the application behaves consistently in each environment.
Overall, application.properties
provides a flexible and powerful way to configure Spring Boot applications, making them easier to develop, deploy, and maintain.
What is application.yaml file?
Many Spring Boot applications use application.yaml
file instead of application.properties
file as it provides a more human-readable and flexible way to define application properties. It allows developers to define properties in a hierarchical structure, supports complex data structures, and provides type safety. Additionally, application.yaml
provides a simpler syntax compared to application.properties
, which can help reduce errors caused by incorrect property syntax.
Here’s an example of how to define properties in application.yaml
:
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost/mydb username: myuser password: mypassword logging: level: root: info org: springframework: debug
application.properties vs application.yaml
Both application.properties
and application.yaml
are configuration files used in Spring Boot to customize the application properties. However, there are some differences between these two files:
- Syntax: The most obvious difference between the two is the syntax they use.
application.properties
uses a simplekey=value
syntax, whereasapplication.yaml
uses YAML syntax, which is more human-readable and supports complex data structures like lists, maps, and nested objects. - Property hierarchy:
application.properties
uses a flat property hierarchy, which means that all properties are stored at the same level. On the other hand,application.yaml
supports a hierarchical property structure, which allows for better organization and easier management of configuration properties. - Type safety: YAML is a type-safe language that allows the specification of data types, which can help reduce errors caused by type mismatches. In contrast, properties in
application.properties
are treated as strings by default, which can lead to errors if they are used incorrectly. - Property precedence: Both files support property precedence, which means that properties can be overridden by properties defined in other files or through command-line arguments. However,
application.yaml
provides more flexibility in property precedence, allowing properties to be defined at different levels of the configuration hierarchy.
Read properties Using the Environment Object
A simple way to access information from the application.properties file is by autowiring an Environment object. This can be done by adding the @Autowired annotation. This process is known as dependency injection.
To use field-based dependency injection and inject the Environment object, you can follow these steps:
- Use the @Autowired annotation to inject the Environment object into your Rest Controller or Service class.
@Autowired private Environment env;
- Use the method called “getProperty” by providing it with the property’s key to get a specific property’s value.
String keyValue = env.getProperty(key);
Let’s say I have these properties in my application.properties file:
app.title=Learning Spring Boot app.description=Working with properties file
And I have to create a Web Service endpoint that takes the name of a property key as a request parameter and gives back the value of the property.
Here is my Rest Controller class
package com.appsdeveloperblog.properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("app") public class AppController { @Autowired private Environment env; @GetMapping("/property") public String getPropertyValue(@RequestParam("key") String key) { String returnValue = "No value"; String keyValue = env.getProperty(key); if( keyValue!= null && !keyValue.isEmpty()) { returnValue = keyValue; } return returnValue; } }
To read a property from the application.properties file, I used the @Autowired annotation to inject the Environment object. After that, I could use the getProperty(String key) method to get the value of the property I needed.
Read Properties using the @Value Annotation
Another very simple way to read the “application.properties” is to use the @Value annotation. You can use it to read a value from a properties file and assign it to a variable, including the property name in brackets. For instance, if you want to get the value of “app.title” property, you can use @Value annotation like this:
@Value("${app.title}") private String appTitle;
Let’s say I have the following “application.properties” file:
app.title=Learning Spring Boot app.description=Working with properties file
Here is a Rest Controller example that reads the “app.title” property using the @Value annotation:
package com.appsdeveloperblog.properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("app") @Value("${app.title}") private String appTitle; @GetMapping("/value") public String getValue() { return appTitle; } }
Read Properties using the @ConfigurationProperties Annotation
A different method to read application properties in a Spring Boot application is by using the @ConfigurationProperties annotation. This requires creating a Plain Old Java Object where each field’s value corresponds to the key name in the settings file.
For instance, let’s say we have the same “application.properties” file that we used in the last section:
app.title=Learning Spring Boot app.description=Working with properties file
We need to add an annotation to our Java Bean with the prefix “app” because all of the property names start with that prefix. The annotation we need to use is called @ConfigurationProperties(“app”).
Here is an example of a Java class annotated with the @ConfigurationProperties annotation:
package com.appsdeveloperblog.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties("app") public class AppProperties { private String title; private String description; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
To use this class in a Rest Controller or a Service class, we can inject its object by using the @Autowired annotation:
package com.appsdeveloperblog.properties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("app") public class AppController { @Autowired AppProperties myAppProperties; @GetMapping("/title") public String getAppTitle() { return myAppProperties.getTitle(); } @GetMapping("/description") public String getAppDescription() { return myAppProperties.getDescription(); } }
We can retrieve the value of a property from the “application.properties” file by using getters on an instance of the “AppProperties” class.
Here it is! These are three easy ways to read application properties in your Spring Boot application.
Environment object vs @Value annotation
When it comes to reading properties in a Spring Boot application, there are two main approaches: using the Environment
object and using the @Value
annotation. While both methods can achieve the same goal, there are some key differences that are worth considering.
Flexibility
One of the key differences between using the Environment
object and the @Value
annotation is the level of flexibility each approach offers.
The Environment
object provides a programmatic way to access properties, and it can be used in any Spring-managed component or bean. With the Environment
object, you can access properties in a hierarchical manner using dot notation. For example:
String myNestedProperty = env.getProperty("my.nested.property");
And you can also specify default values if a property is not found, like so:
String myProperty = env.getProperty("my.property", "default value");
This level of flexibility makes the Environment
object a great choice for more complex property configurations.
On the other hand, the @Value
annotation is a simpler and more concise approach that is best suited for injecting individual properties or small groups of properties into your classes or beans. While the @Value
annotation does offer some level of flexibility (such as being able to specify default values), it is generally not as powerful as the Environment
object in terms of hierarchical property access or programmatic property manipulation.
Configuration Style
Another difference between the Environment
object and the @Value
annotation is their configuration style.
With the Environment
object, properties are typically defined in external configuration files (such as application.properties
or application.yml
), and are then accessed programmatically using the Environment
object. This separation of configuration and code can be beneficial for larger applications that require more complex property management.
On the other hand, the @Value
annotation typically involves defining properties directly in code using SpEL (Spring Expression Language) syntax. While this can be more convenient for smaller applications or simple property configurations, it can make it more difficult to manage larger property sets or to update properties without modifying code.
Integration with Non-Spring Classes
Finally, another difference between using the Environment
object and the @Value
annotation is how they integrate with non-Spring classes.
The Environment
object can be used in any Spring-managed component or bean, but it can be more difficult to use in non-Spring classes (such as JPA entities). This is because the Environment
object requires autowiring and is typically accessed via programmatic code.
On the other hand, the @Value
annotation can be used to inject properties into non-Spring classes using the @Configurable
annotation. This can be a more convenient approach for certain use cases where non-Spring classes need to access application properties.
Overall, both the Environment
object and the @Value
annotation have their strengths and weaknesses, and the best approach will depend on the specific requirements of your application. By understanding the differences between these two approaches, you can choose the one that best fits your needs and make the most of Spring Boot’s powerful configuration framework.
The order of precedence when reading properties in a Spring Boot application
When a Spring Boot application starts up, it reads properties from multiple sources, including command line arguments, environment variables, and application.properties (or application.yml) files. These sources are read in a specific order of precedence, with later sources overriding earlier sources.
The order of precedence for property sources is as follows:
- Command line arguments: Properties passed as command line arguments when starting the application take the highest precedence. For example, you can specify a property with the
--my.property=value
flag to override the value defined in any other property source. - Environment variables: Properties defined as environment variables take the second highest precedence. For example, you can set an environment variable
MY_PROPERTY
with the valuevalue
to override the value defined in any other property source. - Application properties files: Properties defined in application.properties or application.yml files take the third highest precedence. If a property is defined in both application.properties and application.yml files, the value defined in application.yml takes precedence.
- Default properties: Properties defined in Spring Boot’s default configuration files take the lowest precedence. These properties are defined in
spring-boot.jar!/org/springframework/boot/autoconfigure/
and are used when no other property sources define the property.
By default, Spring Boot will search for application.properties and application.yml files in the classpath and load them in the order described above. However, you can also specify additional property sources or change the order of precedence by using the spring.config.name
and spring.config.location
properties.
Understanding the order of precedence when reading properties is important for configuring your Spring Boot application correctly and ensuring that the right values are used for different environments and deployment scenarios.
Final words
In this tutorial, we’ve learned how to read properties from application.properties files in a Spring Boot application using different approaches. We’ve also discussed the purpose of application.properties and provided examples of common properties that can be configured in it. Furthermore, we’ve explained the order of precedence when reading properties in a Spring Boot application, which is important for understanding how different property sources interact.
I hope you found this tutorial useful. If you want to learn more about Spring Boot, you can watch some video courses listed below. They can help you learn faster. Watching video lessons step-by-step is an easy and fun way to learn Spring Boot. Also, don’t forget to check out the Spring Boot Tutorials page for more related topics.
When I read the properties file from src/main/resources/env.properties
hostName:1.1.1.1
userName:test
Password:test
In Controller
@value(${userName})
Private String userName;
Instead of test it’s is loading system logged in userName.Could someone help on this to learn in right way.
But on the other hand when I update the key in env.properties as name as well as in controller it’s picking the right value