Introduction
Properties files enable you to configure and update your application with different settings separately. You can define and utilize multiple properties files within your application. In this article, we will demonstrate how to define properties files and how to retrieve values from them within your application.
Let’s begin by categorizing the usage of properties into declaration and value retrieval.
Properties Files
Spring provides a way to externalize your configurations using .properties files located in the project’s classpath and resources directory. This allows your configurations to be dynamically configured based on the environment and is very useful for multiple environment setups.
The resources directory is not provided by Spring but rather by the directory structure of Maven and Gradle. During the build step, Maven and Gradle will fetch files from here and place them in the appropriate location in the runtime classpath for your use.
YAML Properties Files
YAML (YAML Ain’t Markup Language) is a human-readable data serialization format that is often used for configuration files. It is designed to be easy to read and write, making it a popular choice for various applications, including Spring framework configuration.
Advantages of YAML Properties Files: YAML offers several advantages for configuration purposes:
- Readability: YAML files use indentation to define the structure, which makes them easy to read and understand.
- Conciseness: YAML files require less syntax compared to traditional XML or even JSON formats.
- Support for Complex Structures: YAML supports nested structures and lists, making it suitable for representing complex configurations.
Example of YAML Properties File:
Consider a simple example where you want to define database configuration using a YAML properties file.
# application.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
jpa:
hibernate:
ddl-auto: update
show-sql: true
Accessing Values in Properties Files
Now, let’s move on to the main topic, which is how to access the values in the properties files mentioned above. However, please note the different usage methods for Spring Framework and Spring Boot projects while reviewing the headings.
Using the @Value Annotation
The @Value
annotation is used in Spring Framework to inject values from properties files, environment variables, system properties, or other Spring beans into your Spring components. It is a flexible way to externalize configuration and make it available within your application.
Here’s how you can use the @Value
annotation to access values from properties files:
Injecting a Single Value:You can use the @Value
annotation to directly inject a single value into a field, constructor, or method parameter of your Spring bean. This value can be retrieved from a properties file.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MyComponent {
@Value("${my.property.key}") // Injects the value of "my.property.key"
private String myPropertyValue;
// Other class members and methods...
}
Using Default Values:
You can provide a default value using the @Value
annotation. If the property is not defined in the properties file, the default value will be used.
@Value("${unknown.property:default-value}")
private String unknownProperty;
Regardless of whether it’s a Spring Boot or Spring Framework project, in order to inject values using the
@Value
annotation, the classes where you use the@Value
annotation should be located within the Spring Context.
Usage of the @PropertySource
Annotation
The Spring @PropertySource
annotation is used to provide properties files to the Spring Environment. This annotation is used in conjunction with @Configuration
classes or classes where you use the @Value
annotation.
We use the @PropertySource
annotation in the following situations:
- When defining properties files other than the application.properties file in a Spring Boot project.
- When defining properties files in a Spring Framework project.
In our example, by creating a admin.properties file in the resources directory, we move the key named admin.name into this file. Then, we add the @PropertySource
annotation to our class named Admin.
@Getter
@Component
@PropertySource("classpath:admin.properties")
public class Admin {
@Value("${admin.name}")
private String name;
}
Let’s add another class named User and access the value user.name in the same way.
@Getter
@Component
@PropertySource(“classpath:user.properties”)
public class User {
@Value("${user.name}")
private String name;
@Value("${admin.name}")
private String blogName;
}
In the example, as you can observe, even though we only configured the user.properties file in our User class, we can still access the keys from the admin.properties file that we set in the Admin class.
Using the @ConfigurationProperties Annotation
The @ConfigurationProperties
annotation is a powerful feature in Spring Boot that enables developers to bind external configuration properties directly to Java objects. This annotation simplifies the process of loading and using configuration properties in your application by eliminating the need to manually retrieve properties from property files or environment variables.
To use the @ConfigurationProperties
annotation, follow these steps:
- Create a Configuration Properties Class: Define a Java class that corresponds to the structure of your configuration properties. Each field in this class represents a configuration property.
- Annotate with @ConfigurationProperties: Annotate your configuration properties class with the
@ConfigurationProperties
annotation. You can provide the prefix that corresponds to your configuration properties in this annotation. - Enable Configuration Properties: Make sure that you’ve enabled configuration properties scanning in your Spring Boot application. This can be done by adding
@EnableConfigurationProperties
to one of your configuration classes or main application class. - Use the Configuration Properties: Once the configuration properties class is annotated and properly set up, Spring Boot will automatically bind the values from the properties files to the corresponding fields in the class. You can then inject the configuration properties class into other components and use the values directly.
Here’s a simple example of how to use the @ConfigurationProperties
annotation:
Assume you have the following properties defined in your application.properties
file:
app.user.username=JohnDoe
app.user.age=30
You can create a configuration properties class like this:
@ConfigurationProperties(prefix = "app.user")
public class UserProperties {
private String username;
private int age;
// getters and setters
}
In your configuration class or main application class, enable configuration properties scanning:
@EnableConfigurationProperties(UserProperties.class)
Then, you can inject the UserProperties
class into your components and use the configuration values:
@Service
public class UserService {
private final UserProperties userProperties;
public UserService(UserProperties userProperties) {
this.userProperties = userProperties;
}
public String getUsername() {
return userProperties.getUsername();
}
public int getAge() {
return userProperties.getAge();
}
}
Conclusion
Finally, managing configuration properties in Spring apps is critical for ensuring flexibility, maintainability, and adaptability. Spring provides versatile tools to efficiently handle configuration values, enabling developers to streamline application setup and enhance overall functionality, whether using annotations like @Value, @PropertySource, or leveraging the power of @ConfigurationProperties.