Why You Should Use @ConfigurationProperties Instead of @Value in Spring Boot

If you've been working with Spring Boot for a while, you've probably reached for the @Value annotation more than once. It’s quick, it’s convenient, and it just works. But as your project grows, this convenience can quietly become chaos. In this post, I’ll walk you through why @ConfigurationProperties is a better long-term solution for handling external configuration — and how to start using it effectively. The Problem With Scattered @Value Annotations Let’s start with a common use case: @Value("${app.timeout}") private int timeout; Simple, right? Now imagine you're managing a dozen settings like this: app.name app.timeout app.retry.count app.retry.delay …spread across multiple classes. Before long, you’re: Hunting through files for property names Struggling to keep config organized Missing validation on important values It works — but it doesn’t scale. A Cleaner Approach: @ConfigurationProperties Spring Boot gives us a much more maintainable way to bind external configuration to Java objects: @ConfigurationProperties. ** Step 1: Define a Properties Class ** @Component @ConfigurationProperties(prefix = "app") public class AppProperties { private String name; private int timeout; private Retry retry = new Retry(); public static class Retry { private int count; private long delay; // getters & setters } // getters & setters } Step 2: Add the Configuration to application.yml or .properties app: name: MyApp timeout: 30 retry: count: 3 delay: 500 Step 3: Inject and Use It @Service public class MyService { private final AppProperties appProperties; public MyService(AppProperties appProperties) { this.appProperties = appProperties; } public void performTask() { System.out.println("Timeout: " + appProperties.getTimeout()); } } Why This Is Better Logical Grouping: Related config is encapsulated in one place. Validation: Add @Validated and use annotations like @NotNull, @Min, etc. Testability: Easily mock or provide test configs. Maintainability: Add new configs without cluttering codebase. Bonus: Use @ConstructorBinding for Immutable Config If you're using Spring Boot 2.2+, you can go even further with immutability: @ConfigurationProperties(prefix = "app") @ConstructorBinding public class AppProperties { private final String name; private final int timeout; public AppProperties(String name, int timeout) { this.name = name; this.timeout = timeout; } // getters only } Final Thoughts Use @Value for quick one-offs. But when you see yourself reusing or grouping configurations — even just 3-4 related values — switch to @ConfigurationProperties. It’s one of those changes that doesn’t just make your code cleaner, but also smarter. SpringBoot #Java #Configuration #CleanCode #SoftwareEngineering #BackendDevelopment

Apr 13, 2025 - 18:38
 0
Why You Should Use @ConfigurationProperties Instead of @Value in Spring Boot

If you've been working with Spring Boot for a while, you've probably reached for the @Value annotation more than once. It’s quick, it’s convenient, and it just works. But as your project grows, this convenience can quietly become chaos.

In this post, I’ll walk you through why @ConfigurationProperties is a better long-term solution for handling external configuration — and how to start using it effectively.

The Problem With Scattered @Value Annotations
Let’s start with a common use case:

@Value("${app.timeout}")
private int timeout;

Simple, right? Now imagine you're managing a dozen settings like this:

  • app.name
  • app.timeout
  • app.retry.count
  • app.retry.delay
  • …spread across multiple classes.

Before long, you’re:

  • Hunting through files for property names
  • Struggling to keep config organized
  • Missing validation on important values

It works — but it doesn’t scale.

A Cleaner Approach: @ConfigurationProperties
Spring Boot gives us a much more maintainable way to bind external configuration to Java objects: @ConfigurationProperties.

** Step 1: Define a Properties Class **

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private int timeout;
    private Retry retry = new Retry();

    public static class Retry {
        private int count;
        private long delay;

        // getters & setters
    }

    // getters & setters
}

Step 2: Add the Configuration to application.yml or .properties

app:
  name: MyApp
  timeout: 30
  retry:
    count: 3
    delay: 500

Step 3: Inject and Use It

@Service
public class MyService {

    private final AppProperties appProperties;

    public MyService(AppProperties appProperties) {
        this.appProperties = appProperties;
    }

    public void performTask() {
        System.out.println("Timeout: " + appProperties.getTimeout());
    }
}

Why This Is Better

  • Logical Grouping: Related config is encapsulated in one place.
  • Validation: Add @Validated and use annotations like @NotNull, @Min, etc.
  • Testability: Easily mock or provide test configs.
  • Maintainability: Add new configs without cluttering codebase.

Bonus: Use @ConstructorBinding for Immutable Config

If you're using Spring Boot 2.2+, you can go even further with immutability:

@ConfigurationProperties(prefix = "app")
@ConstructorBinding
public class AppProperties {
    private final String name;
    private final int timeout;

    public AppProperties(String name, int timeout) {
        this.name = name;
        this.timeout = timeout;
    }

    // getters only
}

Final Thoughts

Use @Value for quick one-offs. But when you see yourself reusing or grouping configurations — even just 3-4 related values — switch to @ConfigurationProperties.

It’s one of those changes that doesn’t just make your code cleaner, but also smarter.

SpringBoot #Java #Configuration #CleanCode #SoftwareEngineering #BackendDevelopment