skip to content

What is @ConfigurationProperties and how does it differ from @Value?

level: juniorimportance: must knowfreq 78%

answer

  1. group vs single value
  2. prefix + type-safe bean
  3. @Value = one placeholder, no relaxed binding
  4. must register the bean
  5. type conversion via Binder

basics

~10 s

@ConfigurationProperties binds a whole group of external properties (from application.yml/properties/env) onto the fields of a POJO in a type-safe way. @Value injects a single property value into one field using a placeholder expression.

solid answer

~40 s

@ConfigurationProperties maps a tree of external configuration (prefixed keys from application.yml, .properties, environment variables) onto a strongly-typed Java bean, converting types and supporting nested objects, lists and maps. You bind once per group and get compile-time-friendly, testable config. @Value injects one value at a time via a SpEL/placeholder string like ${server.port}, with no relaxed binding, no nested-object support, and no built-in validation. Use @ConfigurationProperties for cohesive groups of settings (recommended by Spring Boot); use @Value for a single, occasionally-computed value. To activate a @ConfigurationProperties bean you either annotate it and register with @EnableConfigurationProperties, put @Component on it, or let @ConfigurationPropertiesScan discover it.

code

java · 22 lines
java
@ConfigurationProperties(prefix = "app.mail")
public class MailProperties {
    private String host;
    private int port = 25;
    private List<String> bcc = new ArrayList<>();

    public String getHost() { return host; }
    public void setHost(String host) { this.host = host; }
    public int getPort() { return port; }
    public void setPort(int port) { this.port = port; }
    public List<String> getBcc() { return bcc; }
    public void setBcc(List<String> bcc) { this.bcc = bcc; }
}

@Configuration
@EnableConfigurationProperties(MailProperties.class)
class MailConfig {
    @Bean
    MailSender sender(MailProperties props) {
        return new SmtpMailSender(props.getHost(), props.getPort());
    }
}

go deeper

for a junior

Know it's type-safe group binding by prefix vs @Value's single-value placeholder.

for a middle

Explain activation options and the relaxed-binding/validation/nested differences from @Value.

for a senior

Discuss the Binder, conversion service, and when each approach is architecturally appropriate.

for a principal

Frame config as a bounded, validated, testable contract; standardize on @ConfigurationProperties and metadata for the whole codebase.

## The problem it solves Applications read settings from *external configuration*: `application.properties`/`application.yml`, environment variables, command-line args, etc. Spring exposes all of these through the `Environment`. You could pull each value out one by one, but that scatters config all over the code and gives no type safety. ## @ConfigurationProperties `@ConfigurationProperties` (package `org.springframework.boot.context.properties`) binds a *group* of external properties sharing a common `prefix` onto the fields of a Java/Kotlin bean. ```java @ConfigurationProperties(prefix = "app.mail") public class MailProperties { private String host; // binds app.mail.host private int port; // binds app.mail.port private List<String> bcc; // binds app.mail.bcc[0], [1], ... // getters/setters } ``` Given: ```yaml app: mail: host: smtp.example.com port: 587 bcc: [[email protected], [email protected]] ``` Spring instantiates the bean, walks its properties, and binds each one, performing **type conversion** (String -> int, List, Duration, DataSize, enums, etc.) via the `Binder` and the `ApplicationConversionService`. ## Activating the bean A `@ConfigurationProperties` class is *not* a bean by itself. You must register it one of these ways: 1. `@EnableConfigurationProperties(MailProperties.class)` on a `@Configuration` class. 2. Put `@Component` (or `@ConfigurationProperties` on a `@Bean` factory method). 3. Use `@ConfigurationPropertiesScan` to auto-discover all `@ConfigurationProperties`-annotated classes in given packages. ## @Value contrast `@Value("${server.port}")` injects **one** value using property placeholders (and can use SpEL, e.g. `@Value("#{systemProperties['x']}")`). Differences: - **Granularity**: one value vs. a whole group. - **Relaxed binding**: `@ConfigurationProperties` supports it; `@Value` does **not** — the placeholder must match the exact property name. - **Nested/collection binding**: only `@ConfigurationProperties`. - **Validation**: `@ConfigurationProperties` supports JSR-303 `@Validated`; `@Value` does not (natively). - **Metadata**: `@ConfigurationProperties` participates in IDE metadata (`spring-configuration-metadata.json`). ## When to use which Use `@ConfigurationProperties` for cohesive configuration (recommended default in Spring Boot). Use `@Value` for a single standalone value or when you need a small SpEL computation. ## Gotchas - Forgetting to register the bean -> nothing binds, all fields null/default. - With classic (setter) binding you need setters; missing setters silently skip fields. - `@Value` cannot bind a list/map from a single property cleanly.

  • How do you make a @ConfigurationProperties class an actual Spring bean?
    Register it via @EnableConfigurationProperties(X.class), annotate it with @Component, expose it from an @Bean method, or enable @ConfigurationPropertiesScan to auto-discover it.
  • Can @Value use relaxed binding?
    No. @Value placeholders must match the exact property name; relaxed binding (kebab/camel/underscore equivalence) applies only to @ConfigurationProperties.

saying these in an interview costs you the question

  • Claiming @Value supports relaxed binding
  • Saying a @ConfigurationProperties class becomes a bean automatically without any registration
  • Thinking @Value can bind nested objects or lists like @ConfigurationProperties

context