Skip to main content

1.5 Externalized Configuration & Profiles

← Back to Chapter 1: Spring & Spring Boot Fundamentals

Modern cloud-native systems require externalized configuration so the exact same binary package can run unchanged across local development, staging, QA, and production environments.


@Value vs @ConfigurationProperties​

Feature@Value("${property}")@ConfigurationProperties(prefix = "...")
Type SafetyNo (runtime failure on type mismatch)Yes (strongly typed Java Bean or Record)
Relaxed BindingLimitedFull (kebab-case, camelCase, UPPER_SNAKE_CASE work identically)
JSR-380 ValidationNoYes (supports @NotNull, @Min, etc.)
IDE Auto-completionWeakRich (via spring-boot-configuration-processor)
Best Used ForOne-off individual primitives or flagsCohesive groups of structured configurations

Type-Safe Configuration Example (Java Record)​

@ConfigurationProperties(prefix = "app.mail")
@Validated
public record MailProperties(
@NotBlank String host,
@Min(1) @Max(65535) int port,
@Email String senderAddress,
Duration timeout
) {}

In application.yml:

app:
mail:
host: smtp.sendgrid.net
port: 587
sender-address: noreply@codewithsarvy.dev
timeout: 5s

What are Spring Profiles?​

Our spring boot application can run on different environments like dev,test,prod etc.These are called profiles. For each profile we can have different configurations.

For example:

Development
Testing
Production

You don't want to use the production database while developing locally.

So we can have:

application.properties
application-dev.properties
application-test.properties
application-prod.properties

For example:

application-dev.properties

server.port=8081

and:

application-prod.properties

server.port=8080

Then we can activate a profile.

spring.profiles.active=dev

Now Spring Boot loads the development configuration.

Why are Profiles important?​

Because the same application can run in different environments with different configurations.

For example:

Same application
|
---------------------------
| | |
DEV TEST PROD
| | |
DB-DEV DB-TEST DB-PROD

The code remains mostly the same; configuration changes according to the environment.

Environment Profiles Management​

Profiles allow segregation of environment-specific beans and properties:

# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
username: sa
password: ""
logging:
level:
org.springframework: DEBUG
# application-prod.yml
spring:
datasource:
url: jdbc:postgresql://db.prod.internal:5432/appdb
username: ${DB_USER}
password: ${DB_PASSWORD}
logging:
level:
root: INFO

Activating Profiles:​

  • In application.yml: spring.profiles.active: dev
  • Via OS Environment variable: SPRING_PROFILES_ACTIVE=prod
  • Via CLI parameter: java -jar app.jar --spring.profiles.active=prod

Conditional Beans per Profile​

@Bean
@Profile("dev")
public PaymentGateway mockPaymentGateway() {
return new MockPaymentGateway();
}

@Bean
@Profile("prod")
public PaymentGateway realPaymentGateway() {
return new StripePaymentGateway();
}