Configuration & Properties
Externalize your settings. application.properties / application.yml hold configuration outside the code, @Value injects single values, and @ConfigurationProperties binds whole groups to typed objects.
Learn Configuration & Properties in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You should understand Spring beans and dependency injection , since configuration values are injected into beans. No prior YAML knowledge is required.
What You'll Learn
The Big Idea — Dials on the Outside of the Box
💡 Analogy: Hardcoding settings is like soldering the volume at one level inside a sealed radio — to change it you must open and rebuild the device. Externalized configuration puts the dials on the outside : the same radio (your one build) runs anywhere, and you just turn the knobs ( application.properties , environment variables) for each room. @Value reads one dial; @ConfigurationProperties reads a whole labeled panel of related dials at once.
Build once, configure per environment — never recompile to change a value.
1️⃣ The Configuration Files
Spring Boot auto-loads application.properties (flat key=value ) or application.yml (nested). They are equivalent — a nested YAML key maps to a dotted property key.
2️⃣ Injecting Single Values — @Value
@Value("${key}") injects one property. Add a default after a colon — ${app.timeout:30} — so a missing key falls back gracefully.
3️⃣ Binding Groups — @ConfigurationProperties
For many related settings, @ConfigurationProperties(prefix = "app") binds the whole group — including nested objects and lists — to a typed class. Relaxed binding maps app.support-email to a supportEmail field.
🧠 Quick Recall
Answer: a default used only when app.timeout is missing.
Answer: app.support-email (relaxed binding maps kebab-case to camelCase).
Answer: so one build runs in every environment by changing values, not recompiling code.
🎯 YOUR TURN — Inject payment settings
Use @Value to inject an API URL, a currency (with a default), and a retry count.
🧩 MINI-CHALLENGE — Bind a storage group
Bind a storage.* group — including a list — with @ConfigurationProperties .
Common Errors
- ❌ Hardcoding settings in Java. Needs a rebuild to change. Fix: externalize to a properties/YAML file.
- ❌ Missing @Value default. A missing key fails startup. Fix: add ${key:default} .
- ❌ No getters/setters for @ConfigurationProperties. Binding fails silently. Fix: add accessors (or use a record/constructor binding).
- ❌ YAML indentation mistakes. Wrong structure or parse error. Fix: use consistent spaces, never tabs.
- ❌ Committing secrets to the file. Leaks credentials. Fix: use environment variables / a secrets manager.
- ❌ Scattering many @Value fields. Hard to maintain. Fix: group with @ConfigurationProperties .
Pro Tips
- 💡 Prefer @ConfigurationProperties for any group of related settings — it is type-safe and validatable.
- 💡 Keep secrets out of files — inject them via environment variables at runtime.
- 💡 Override per environment with command-line args or env vars rather than editing the build.
- 💡 Always supply defaults for optional values so missing keys don't break startup.
📋 Quick Reference
Element
Purpose
Note
application.properties
flat key=value
Auto-loaded
application.yml
nested config
Same keys
@Value("${k}")
inject one value
Single property
${k:default}
fallback value
If key missing
@ConfigurationProperties
bind a group
Typed object
prefix = "app"
group namespace
app.* keys
relaxed binding
kebab -> camel
support-email
List binding
CSV / YAML list
to List/array
override
env var / CLI arg
Per environment
📚 Resources / Keep Learning
- 📘 Spring Boot — externalized configuration (docs.spring.io)
- 📗 Type-safe @ConfigurationProperties (docs.spring.io)
- 📗 Using @Value (docs.spring.io)
❓ Frequently Asked Questions
🎉 Lesson Complete!
You can now externalize settings in application.properties or application.yml , inject single values with @Value and defaults, bind whole groups with @ConfigurationProperties , and override values per environment without recompiling.
Next up: Profiles & Environments — switching configuration with @Profile and spring.profiles.active .
Practice quiz
What is the main purpose of application.properties (or application.yml)?
- To externalize configuration outside the code
- To compile the app
- To define database tables
- To replace controllers
Answer: To externalize configuration outside the code. These files externalize configuration so settings can change without recompiling the application.
What does @Value("${server.port}") do?
- Defines a bean
- Injects the value of the server.port property
- Starts a server
- Creates a property file
Answer: Injects the value of the server.port property. @Value injects a single property value, resolving the ${...} placeholder from the configuration.
In @Value("${app.timeout:30}"), what is the 30?
- A bean id
- A port number
- A default used when app.timeout is missing
- A timeout in hours required
Answer: A default used when app.timeout is missing. The text after the colon is the default value used if the property is not defined.
What does @ConfigurationProperties(prefix = "app") bind?
- A single value only
- A REST endpoint
- A SQL query
- A group of properties under the app prefix to a typed object
Answer: A group of properties under the app prefix to a typed object. @ConfigurationProperties binds a whole group of related properties (under a prefix) to fields of a class.
Which approach is better for many related settings?
- Many separate @Value fields
- @ConfigurationProperties on a typed class
- Hardcoding in Java
- Environment variables only
Answer: @ConfigurationProperties on a typed class. @ConfigurationProperties groups related settings into one type-safe, validated object, which scales better than many @Value fields.
How is a nested YAML property app.mail.host referenced as a flat key?
- app.mail.host
- app-mail-host
- app/mail/host
- appMailHost
Answer: app.mail.host. YAML nesting maps to dotted keys, so app: mail: host becomes app.mail.host.
Why externalize configuration instead of hardcoding it?
- It is required by Java
- It makes code longer
- So the same build runs with different settings per environment
- It disables logging
Answer: So the same build runs with different settings per environment. Externalized config lets one immutable build run anywhere by changing values, not code.
Which is a valid way to override a property at runtime?
- Editing the JAR bytes
- Recompiling for each value
- It cannot be overridden
- A command-line argument or environment variable
Answer: A command-line argument or environment variable. Spring Boot lets command-line args and environment variables override file-based properties.
What type can @ConfigurationProperties bind a comma-separated list to?
- Only String
- A List or array field
- Only int
- Nothing
Answer: A List or array field. Spring Boot can relax-bind comma-separated values (or YAML lists) to a List or array field.
What does the missing-key default in @Value("${k:fallback}") prevent?
- Slow startup
- A startup failure when the property is absent
- Extra logging
- A compile error
Answer: A startup failure when the property is absent. Providing a default after the colon lets the bean start even when the property is not defined.
Continue this course
- Previous: DTOs & Mapping
- Next: Profiles & Environments