1. Introduction
Spring Boot's @ConfigurationProperties annotation provides a convenient way to bind external configurations, such as those specified in application.properties or application.yml files, to structured objects. Leveraging this feature allows for more type-safe configuration and makes it easier to maintain as the number of configuration properties grows. In this blog post, we'll look at how to use @ConfigurationProperties to externalize application settings into a POJO (Plain Old Java Object).
Key Points:
1. @ConfigurationProperties enables binding of property files to POJOs for easy access and strong typing.
2. It supports nested properties and provides validation through JSR-303/JSR-349 if validation API is on the classpath.
3. This annotation promotes a cleaner code base by avoiding the widespread use of @Value.
4. Property keys are automatically mapped to object fields, even with different naming conventions (kebab, camelCase, etc.).
5. @ConfigurationProperties can be meta-annotated with @Component or used with @EnableConfigurationProperties to register the properties bean.
2. Implementation Steps
1. Create a POJO class to hold configuration properties.
2. Annotate the POJO class with @ConfigurationProperties and define its prefix.
3. Optionally include validation annotations in the POJO class.
4. Register the properties class as a bean, either with @Component or within a configuration class using @EnableConfigurationProperties.
5. Define the properties in the application.properties or application.yml file.
6. Inject the properties class into components where configuration values are needed.
3. Implementation Example
// Step 1: Define the POJO class to hold configuration properties
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
private String hostName;
private int port;
private String from;
// Getters and setters for each property
// ...
}
// Step 2: Annotate the POJO class for validation
import jakarta.validation.constraints.NotNull;
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
@NotNull
private String hostName;
private int port;
private String from;
// Getters and setters
// ...
}
// Step 3: Register the properties class as a bean
// Option 1: Annotate with @Component
@Component
public class MailProperties {
// ...
}
// Option 2: Use @EnableConfigurationProperties in a @Configuration class
@Configuration
@EnableConfigurationProperties(MailProperties.class)
public class Config {
// ...
}
// Step 4: Define the properties in application.properties
/*
mail.host-name=smtp.example.com
mail.port=587
mail.from=no-reply@example.com
*/
// Step 5: Inject and use the MailProperties bean
@Service
public class MailService {
private final MailProperties properties;
public MailService(MailProperties properties) {
this.properties = properties;
}
public void printMailConfig() {
System.out.println("Mail host: " + properties.getHostName());
System.out.println("Mail port: " + properties.getPort());
System.out.println("Mail from: " + properties.getFrom());
}
}
// Step 6: Run the application
@SpringBootApplication
public class ConfigurationPropertiesApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(ConfigurationPropertiesApplication.class, args);
MailService mailService = ctx.getBean(MailService.class);
mailService.printMailConfig();
}
}
Output:
Mail host: smtp.example.com Mail port: 587 Mail from: no-reply@example.com
Explanation:
1. @ConfigurationProperties(prefix = "mail"): This annotation binds all properties with the prefix mail to the MailProperties class.
2. @NotNull: The hostName field is annotated with @NotNull indicating that this property must be provided.
3. @Component: By annotating MailProperties with @Component, it is automatically detected and registered as a bean by Spring's component-scanning mechanism.
4. @EnableConfigurationProperties(MailProperties.class): As an alternative to @Component, this annotation is used in a configuration class to explicitly enable MailProperties as a bean.
5. application.properties: This file contains the externalized configuration for the mail properties.
6. MailService: This is a service class that uses MailProperties to access the configuration properties.
7. @Service: Marks MailService as a Spring-managed service bean.
8. SpringApplication.run(): Boots the Spring application and creates an application context containing all the beans, including MailProperties populated with the properties from application.properties.