Configuration & Spring Profiles
Keep settings out of your code: read values from application.properties, and switch between dev and prod setups with Spring Profiles.
What you will learn
- Read a setting with @Value and @ConfigurationProperties
- Understand externalized configuration
- Switch settings per environment with profiles
Settings do not belong in code
A database URL, an API key, a page size — these are settings, and they change between your laptop and the real server. Hard-coding them means editing and rebuilding the app for every environment. The professional approach is externalized configuration: keep settings in a file (or environment variables), separate from the code that uses them.
Spring’s home for settings is src/main/resources/application.properties (or the .yml form). You met it for the port and the database. Now let us read our own settings from it.
Read one value with @Value
Put a custom setting in application.properties, then inject it into any bean with @Value:
# application.properties
app.welcome-message=Welcome to CodingClave!
app.page-size=10@RestController
public class HomeController {
// Spring reads the value from application.properties and injects it
@Value("${app.welcome-message}")
private String welcome;
@GetMapping("/")
public String home() {
return welcome;
}
}Note: Output (visiting /): Welcome to CodingClave! The string came from application.properties, not from the code. To change the greeting you edit the properties file and restart — no code change, no rebuild.
Group related settings with @ConfigurationProperties
When you have several related settings, injecting them one @Value at a time gets messy. @ConfigurationProperties binds a whole group (sharing a prefix) into one tidy class:
# application.properties
app.name=CodingClave API
app.page-size=10
app.support-email=help@codingclave.com@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private int pageSize;
private String supportEmail;
// getters and setters — Spring fills these from the app.* keys
}Note: Output:
Spring matches each property to a field (app.name -> name, app.page-size -> pageSize, app.support-email -> supportEmail) and fills the object. Inject AppProperties anywhere and call props.getPageSize() to get 10. All your settings live in one typed object.
Profiles: different settings per environment
Your app needs different settings in different places — H2 on your laptop, MySQL on the server; debug logging in dev, quiet logging in prod. A Spring Profile is a named set of settings for one environment. You put environment-specific files alongside the main one:
| File | Used when |
|---|---|
application.properties | Always (shared defaults) |
application-dev.properties | The “dev” profile is active |
application-prod.properties | The “prod” profile is active |
# application-dev.properties (your laptop)
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.show-sql=true
# application-prod.properties (the real server)
spring.datasource.url=jdbc:mysql://db-server:3306/codingclave
spring.jpa.show-sql=falseNote: Output: You choose the active profile at startup, for example: java -jar app.jar --spring.profiles.active=prod With prod active, Spring loads application-prod.properties on top of the shared one, so the app connects to MySQL and turns off SQL logging — without touching a line of code.
How profiles are chosen, step by step
- Spring always loads
application.propertiesfirst (the shared defaults). - You set the active profile — via
spring.profiles.activein properties, an environment variable, or a--spring.profiles.active=...flag at startup. - Spring then loads the matching
application-<profile>.propertieson top, so its values override the shared ones. - Your app runs with the merged settings for that environment — same code, different config.
Tip: A great split: keep harmless shared defaults in application.properties, put the laptop setup in application-dev.properties, and put real-server settings in application-prod.properties (reading secrets from environment variables, never committing real passwords).
Watch out: Never commit production passwords or API keys into any .properties file in Git. Reference an environment variable instead, e.g. spring.datasource.password=${DB_PASSWORD}, and set the real value on the server only.
Q. What is a Spring Profile used for?
✍️ Practice
- Add a custom
app.page-sizesetting and read it with@Valuein a controller. - Create
application-dev.propertiesandapplication-prod.propertieswith differentspring.jpa.show-sqlvalues and switch between them.
🏠 Homework
- Externalize your app’s name and default page size into application.properties (bound with @ConfigurationProperties), then add dev and prod profiles that use H2 and MySQL respectively.