Skip to main content

2.5 Configuration Properties and 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 (2.4+) looks for application.properties/ application.yml(and application-{profile}.yml) in the following order. Lower numbers indicate higher priority. External files always override packaged files.

PriorityLocationNote
1Command-line locationjava -jar app.jar --spring.config.location=...
2Current dir's /config subdirectories./config/*/application.yml (Useful for separating configs)
3Current directory /config./config/application.yml
4Current directory./application.yml
5Classpath /configclasspath:/config/application.yml
6Classpath rootclasspath:/application.yml (typically src/main/resources)
  • The Power of Externalization: When running a jar, the current directory and ./config override the classpath. You can place an application.yml next to the jar to instantly override packaged defaults without recompiling.
  • spring.config.additional-location: To load additional external files while keeping the default search paths, use this command-line argument: (--spring.config.additional-location=file:./custom.yml).

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.