Overview
Every app needs settings: port, DB URL, feature flags. In Spring Boot they live in application.properties or application.yml under src/main/resources. This page covers where values live, who wins when keys clash, what profiles are, and how @ConfigurationProperties binds settings to Java objects.
Official: Externalized Configuration.
Table of contents
application.yml- Property precedence
- Profiles
@Valuefor single values@ConfigurationPropertiesfor groups- Relaxed binding
- Secrets
- Interview questions
- Summary
1. application.yml
server:
port: 9090
app:
greeting: Hello
Boot loads this into an Environment object. Anything reading server.port now sees 9090.
2. Property precedence
When the same key is set in multiple places, the most specific source wins. Roughly (highest first):
- Command-line args (
--server.port=8081) SPRING_APPLICATION_JSONenv var- Java system properties (
-Dserver.port=8081) - OS environment variables (
SERVER_PORT=8081) application-{profile}.ymlapplication.yml
Why this order matters: Kubernetes/Docker can inject prod values via env vars without rebuilding the JAR.
3. Profiles
A profile is a label like dev, prod, cloud. Activate one:
spring:
profiles:
active: dev
Typical layout:
application.yml # defaults
application-dev.yml # extra when profile=dev
application-prod.yml # extra when profile=prod
You can also gate a bean with @Profile("dev") so it only exists in that profile (e.g. a debug controller).
4. @Value for single values
@Value("${app.greeting:Hello}") // ":Hello" is the default
private String greeting;
Good for one value. Bad for many related keys.
5. @ConfigurationProperties for groups
app:
orders:
timeout: 30s
max-retries: 3
@ConfigurationProperties(prefix = "app.orders")
public record OrderSettings(Duration timeout, int maxRetries) {}
Register it by adding @ConfigurationPropertiesScan to your main class, or @EnableConfigurationProperties(OrderSettings.class).
Bonus: add @Validated + Jakarta validation annotations (@Min, @NotNull) so bad config fails at startup, not at runtime.
6. Relaxed binding
Spring maps environment-variable style to nested keys:
SERVER_PORT→server.portAPP_MY_FEATURE_ENABLED→app.my-feature.enabled
Useful in Docker/Kubernetes where you can’t use dots in env var names.
7. Secrets
Never commit prod passwords or API keys to application-prod.yml in git.
Better:
- Kubernetes Secrets
- HashiCorp Vault
- AWS Parameter Store / Secrets Manager
- Plain env vars at deploy time
Your code reads ${MY_SECRET}; the platform injects the value.
8. Interview questions
Q: @ConfigurationProperties vs @Value?
A: @ConfigurationProperties binds a tree of keys under one prefix into a typed object, with validation. @Value injects one string at a time.
Q: What is a profile?
A: A named environment label (dev, prod) that activates extra config files and @Profile beans.
Q: How can ops change the port without rebuilding?
A: Set server.port via command-line, system property, or SERVER_PORT env var — they all beat the YAML file.
Q: Where should production secrets go? A: A secret manager (Vault, K8s Secrets, AWS SM) injected as env vars — never in committed YAML.
9. Summary
| Topic | One line |
|---|---|
| Files | application.yml + optional application-{profile}.yml |
| Precedence | CLI / env vars beat files |
| Typed config | @ConfigurationProperties with @Validated |
| Secrets | Never in git; inject via the platform |
Next steps
- Web MVC & REST
- Auto-configuration — how defaults pick up
server.*
Happy Learning