Stage 11: Spring Boot, lesson 2 of 8

Configuration, profiles and properties

Intermediate3 min read@since 17Code runs on your Java 25
Explain it forThe essentials plus production detail and pitfalls.

Boot reads configuration from many sources. From highest priority to lowest: command-line arguments, environment variables, application-{profile}.yml, application.yml, then built-in defaults.

  • Profiles: spring.profiles.active=prod loads application-prod.yml on top of the base file. Mark beans with @Profile("dev").
  • Type-safe config: @ConfigurationProperties binds a whole prefix to a record or class, with validation.
  • @Value("${...}") injects a single value.
  • Environment variables map automatically: SPRING_DATASOURCE_URL becomes spring.datasource.url.

Never commit secrets. Inject them from environment variables, Vault or your cloud's secret manager.

Example

YAML
# application.yml
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/javaatlas
    username: app
    password: ${DB_PASSWORD}          # read from the environment
  jpa:
    open-in-view: false
  threads:
    virtual:
      enabled: true                   # Boot 3.2+ on Java 21+

app:
  payments:
    provider: razorpay
    timeout: 5s
    max-retries: 3
---
spring:
  config:
    activate:
      on-profile: prod
logging:
  level:
    root: warn
Bind it type-safely
@ConfigurationProperties(prefix = "app.payments")
@Validated
public record PaymentProps(@NotBlank String provider,
                           Duration timeout,
                           @Min(0) int maxRetries) {}

@SpringBootApplication
@ConfigurationPropertiesScan
public class JavaAtlasApplication { /* ... */ }

Common mistake

Hard-coding environment-specific URLs and passwords in application.yml and committing them to Git.

Under the hood

Relaxed binding maps kebab-case properties (app.payments.max-retries), camelCase Java names (maxRetries) and environment variables (APP_PAYMENTS_MAXRETRIES) to the same value. Duration and DataSize fields accept values like 5s or 10MB. In Kubernetes, pass configuration through environment variables from ConfigMaps and Secrets, or use spring.config.import=configtree:/etc/config/.

Check yourself

Which source has the highest priority?

How this connects

Where this leads

You've reached the end of this thread. Try a learning path for what's next.

Part of Job-ready backend developer, Microservices and production.

Was this lesson helpful?

Finished reading? Mark it complete to track your progress.