Configuration, Profiles & Properties

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

  1. application.yml
  2. Property precedence
  3. Profiles
  4. @Value for single values
  5. @ConfigurationProperties for groups
  6. Relaxed binding
  7. Secrets
  8. Interview questions
  9. 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):

  1. Command-line args (--server.port=8081)
  2. SPRING_APPLICATION_JSON env var
  3. Java system properties (-Dserver.port=8081)
  4. OS environment variables (SERVER_PORT=8081)
  5. application-{profile}.yml
  6. application.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_PORTserver.port
  • APP_MY_FEATURE_ENABLEDapp.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


Happy Learning

Next: Web MVC, REST, Validation & Errors