Spring Boot @ConfigurationProperties Example

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.


Comments