Skip to main content
Advertisement

2.9 Configuration Binding (@ConfigurationProperties)

Use @ConfigurationProperties to bind typed and validated configuration from application.yml instead of many @Value fields. This gives clearer structure and better IDE autocomplete/validation.

Reference: Spring Boot 3.2.x

1. Basic Usage

# application.yml
app:
mail:
host: smtp.example.com
port: 587
security:
jwt-secret: my-secret
token-validity: 3600
@Configuration
@ConfigurationProperties(prefix = "app")
@Validated
@Getter
@Setter
public class AppProperties {

private final Mail mail = new Mail();
private final Security security = new Security();

@Getter
@Setter
public static class Mail {
private String host = "localhost";
private int port = 25;
}

@Getter
@Setter
public static class Security {
@NotBlank
private String jwtSecret;
@Min(60)
private long tokenValidity = 3600;
}
}
  • prefix: Top-level key in yaml (app)
  • @Validated + Bean Validation enables startup-time validation (build fails on missing required values)

2. Enabling Scan

Register with @EnableConfigurationProperties(AppProperties.class) or annotate the class with @Component. Spring Boot auto-scans classes annotated with @ConfigurationProperties, so @Configuration alone is usually sufficient.

3. Profile-Specific Values

# application-dev.yml
app:
mail:
host: mailhog
port: 1025
---
# application-prod.yml
app:
mail:
host: ${MAIL_HOST}
port: ${MAIL_PORT:587}
  • ${ENV_VAR}: Environment variable
  • ${ENV_VAR:default}: Environment variable with default value

4. Constructor Binding (Immutable)

Since Spring Boot 2.2+, you can bind via constructor, making fields final for immutable config.

@ConfigurationProperties(prefix = "app.mail")
@ConstructorBinding // Can be omitted in Boot 3.x if there is only one constructor
@Getter
public class MailProperties {

private final String host;
private final int port;

public MailProperties(String host, int port) {
this.host = host;
this.port = port;
}
}

5. Spring Boot Config File Loading Order and Priority

Application config (application.properties / application.yml) is loaded from multiple locations; later sources override earlier ones for the same key. Higher priority wins.

5.1 Config Search Paths (higher priority first)

Spring Boot looks for application.properties / application.yml (and application-{profile}.properties etc.) in this order. Lower number = higher priority.

PriorityLocationNote
1Current directory /config./config/application.yml
2Current directory./application.yml
3Classpath /configclasspath:/config/application.yml
4Classpath rootclasspath:/application.yml (e.g. src/main/resources)
  • When running jar: Current directory and ./config override classpath, so you can place application.yml or config/application.yml next to the jar to override packaged defaults.

5.2 Profile-Specific vs Common File

  • application.yml: Common; loaded without profile.
  • application-{profile}.yml: Loaded when that profile is active (e.g. application-dev.yml, application-prod.yml).

Override order (same key; later wins):

  1. application.yml (common)
  2. application-{profile}.yml (active profile)

So application-prod.yml overrides application.yml.

5.3 External Config Priority (summary)

For the same key, Spring Boot applies (higher priority wins):

  1. Command line arguments--server.port=8081
  2. SPRING_APPLICATION_JSON (JSON in env var / system property)
  3. ServletConfig / ServletContext (web environment)
  4. JNDI
  5. Java system properties-Dserver.port=8081
  6. OS environment variables
  7. RandomValuePropertySource (random.*)
  8. application-{profile}.yml outside jar
  9. application-{profile}.yml inside jar
  10. application.yml outside jar
  11. application.yml inside jar
  12. @PropertySource
  13. Defaults (SpringBootApplication defaults, etc.)

In practice: defaults in jar application.yml, overrides via application-{profile}.yml or environment variables / command line.

5.4 Summary

  • Path order: ./config/ > ./ > classpath:/config/ > classpath:/
  • File type: application-{profile}.yml overrides application.yml for the same key.
  • External override: Command line and env vars override files, so secrets and ports can be supplied at deploy time.

6. List / Map

app:
allowed-hosts:
- api.example.com
- admin.example.com
features:
new-ui: true
beta: false
private List<String> allowedHosts = new ArrayList<>();
private Map<String, Boolean> features = new HashMap<>();

tip

Use environment variables or Vault for secrets and reference them with ${VAR} in properties. See 5. Config File Loading Order and Priority to see which value wins when multiple sources define the same key.

Advertisement