Home/Learn/Spring Boot/Application Configuration

Application Configuration

Beginner
Core & Setup

application.yml is the central config file. @ConfigurationProperties binds whole config sections to typed classes — the recommended approach for anything beyond a single value. @Value injects individual properties.

Overview

Spring Boot's externalized configuration follows a strict priority order: command-line args override env vars, which override profile-specific files, which override application.yml. @ConfigurationProperties maps a config prefix to a Java record or class — you get type safety, IDE autocompletion, and validation. @Value("${property}") injects a single value directly. Never hardcode secrets in config files — use environment variables or a secrets manager and reference them as ${DB_PASSWORD}.

@ConfigurationProperties — Type-Safe Config

Bind entire config sections to a typed class with @ConfigurationProperties. Spring validates the fields at startup using Bean Validation annotations. Pair with @EnableConfigurationProperties or add @ConfigurationPropertiesScan on your main class.

YAML + Java — @ConfigurationProperties with validation
// application.yml
app:
  jwt:
    secret: ${JWT_SECRET}          # from env var
    expiry-minutes: 60
  email:
    provider: resend
    api-key: ${EMAIL_API_KEY}
    from: noreply@aicancode.org
  rate-limit:
    requests-per-minute: 100
    burst-capacity: 200

// --- Java config class (Java record — Spring Boot 3+) ---
@ConfigurationProperties(prefix = "app.jwt")
public record JwtProperties(
    @NotBlank String secret,
    @Min(5) @Max(1440) int expiryMinutes
) {}

@ConfigurationProperties(prefix = "app.email")
public record EmailProperties(
    @NotBlank String provider,
    @NotBlank String apiKey,
    @Email String from
) {}

// Register in main class
@SpringBootApplication
@ConfigurationPropertiesScan // picks up all @ConfigurationProperties in package
public class App { ... }

// Inject and use
@Service
public class JwtService {
    private final JwtProperties jwt;

    public JwtService(JwtProperties jwt) { this.jwt = jwt; }

    public String generateToken(String userId) {
        return Jwts.builder()
            .subject(userId)
            .expiration(Date.from(Instant.now()
                .plusSeconds(jwt.expiryMinutes() * 60L)))
            .signWith(Keys.hmacShaKeyFor(jwt.secret().getBytes()))
            .compact();
    }
}

@Value and Property Override Hierarchy

Use @Value for simple single-value injection with optional defaults. The override hierarchy matters in production — environment variables always win over YAML, which means you can deploy the same JAR to dev and prod just by changing env vars.

Java + YAML — @Value, override hierarchy, profiles
@Service
public class FeatureFlagService {

    // ${property.name} — fails at startup if missing
    @Value("${feature.dark-mode.enabled}")
    private boolean darkModeEnabled;

    // ${property:default} — uses default if property not set
    @Value("${feature.max-upload-mb:10}")
    private int maxUploadMb;

    // SpEL expression inside @Value
    @Value("#{${app.rate-limit.requests-per-minute} * 60}")
    private int requestsPerHour;
}

// Property override order (highest wins first):
// 1. Command-line args:     java -jar app.jar --server.port=9090
// 2. SPRING_APPLICATION_JSON env var (JSON blob)
// 3. OS environment variables: SERVER_PORT=9090
// 4. application-{profile}.yml (active profile file)
// 5. application.yml (base config)
// 6. @PropertySource annotations
// 7. Default values in @ConfigurationProperties / @Value

// Profiles — activate with:
// spring.profiles.active=prod   (in application.yml)
// SPRING_PROFILES_ACTIVE=prod   (env var)
// java -jar app.jar --spring.profiles.active=prod

# application-prod.yml
spring:
  datasource:
    url: jdbc:postgresql://prod-db.internal:5432/toolhub
    username: ${DB_USER}
    password: ${DB_PASS}
  jpa:
    show-sql: false
logging:
  level:
    root: WARN
    com.aicancode: INFO

Key Points to Remember

  • 1@ConfigurationProperties is preferred for multi-property sections — type-safe, validatable, IDE-autocompletable.
  • 2@Value("${prop:default}") injects a single property with an optional fallback default.
  • 3Command-line args > env vars > application-{profile}.yml > application.yml — env vars always win.
  • 4Never hardcode secrets in YAML — use ${ENV_VAR} references and set them in the runtime environment.
  • 5@ConfigurationPropertiesScan on @SpringBootApplication auto-registers all @ConfigurationProperties.
  • 6Use profile-specific files (application-prod.yml) for environment differences, not if/else in code.

Interview Questions

Sign in to ask Aria
1

What is the difference between @Value and @ConfigurationProperties?

EasyWipro
2

What is the property override order in Spring Boot?

MediumAmazon
3

How do you validate @ConfigurationProperties fields at startup?

MediumThoughtWorks
4

How would you supply a different database URL for dev vs prod without changing code?

EasyInfosys
5

What is relaxed binding in Spring Boot configuration properties?

MediumAtlassian

Ask Aria about Application Configuration

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…