乐闻世界logo
搜索文章和话题

How to implement multi-environment configuration in Spring Boot?

3月6日 21:58

Spring Boot Multi-Environment Configuration

Why Multi-Environment Configuration

In real projects, applications are deployed to different environments:

  • Development (dev): Local development and debugging
  • Testing (test): QA testing and validation
  • Staging: Pre-production validation
  • Production (prod): Live services

Different environments require different configurations: database connections, log levels, service endpoints, etc.

Approach 1: Profile-specific Configuration Files

1. File Naming Convention

shell
application.yml # Default (shared across all environments) application-dev.yml # Development environment application-test.yml # Testing environment application-staging.yml # Staging environment application-prod.yml # Production environment

2. Configuration Examples

application.yml (Default)

yaml
spring: application: name: my-service profiles: active: dev # Default to dev environment server: port: 8080 logging: level: root: INFO

application-dev.yml (Development)

yaml
server: port: 8081 spring: datasource: url: jdbc:mysql://localhost:3306/dev_db username: dev_user password: dev_pass jpa: hibernate: ddl-auto: update show-sql: true logging: level: com.example: DEBUG

application-prod.yml (Production)

yaml
server: port: 80 spring: datasource: url: jdbc:mysql://prod-db.example.com:3306/prod_db username: ${DB_USERNAME} password: ${DB_PASSWORD} hikari: maximum-pool-size: 50 jpa: hibernate: ddl-auto: validate show-sql: false logging: level: root: WARN

Approach 2: Single File with Multiple Documents

Spring Boot 2.4+ supports multiple profiles in one YAML file:

yaml
spring: application: name: my-service --- spring: config: activate: on-profile: dev server: port: 8081 --- spring: config: activate: on-profile: prod server: port: 80

Activating Profiles

Method 1: Configuration File

yaml
spring: profiles: active: dev

Method 2: Command Line

bash
java -jar myapp.jar --spring.profiles.active=prod

Method 3: Environment Variable

bash
export SPRING_PROFILES_ACTIVE=prod java -jar myapp.jar

Method 4: JVM System Property

bash
java -Dspring.profiles.active=prod -jar myapp.jar

Profile Groups (Spring Boot 2.4+)

Group multiple profiles together:

yaml
spring: profiles: group: local: - dev - local-db - local-cache production: - prod - prod-db - prod-cache

Usage:

bash
java -jar myapp.jar --spring.profiles.active=local # Activates: dev, local-db, local-cache

Conditional Bean Configuration

Use @Profile annotation for environment-specific beans:

java
@Configuration public class DataSourceConfig { @Bean @Profile("dev") public DataSource devDataSource() { // Dev datasource configuration } @Bean @Profile("prod") public DataSource prodDataSource() { // Production datasource configuration } @Bean @Profile("!prod") // Non-production environments public MockService mockService() { return new MockService(); } }

Accessing Active Profiles in Code

java
@Component public class EnvironmentChecker implements CommandLineRunner { @Autowired private Environment environment; @Override public void run(String... args) { String[] activeProfiles = environment.getActiveProfiles(); System.out.println("Active profiles: " + String.join(", ", activeProfiles)); if (environment.acceptsProfiles(Profiles.of("dev"))) { System.out.println("Development mode"); } } }

Configuration Loading Priority

Priority order (high to low):

  1. Command line arguments
  2. JNDI properties
  3. Java System properties
  4. OS environment variables
  5. RandomValuePropertySource
  6. External application-{profile}.properties
  7. Internal application-{profile}.properties
  8. External application.properties
  9. Internal application.properties
  10. @PropertySource annotations
  11. SpringApplication default properties

Key Rules:

  • application-{profile}.yml overrides application.yml
  • Higher priority overrides lower priority for same keys

Sensitive Information Encryption

Option 1: Environment Variables

yaml
spring: datasource: password: ${DB_PASSWORD}

Option 2: Jasypt Encryption

yaml
spring: datasource: password: ENC(encrypted_password) jasypt: encryptor: password: ${JASYPT_ENCRYPTOR_PASSWORD}

Best Practices

1. Configuration Layering

yaml
# application.yml - Only truly shared configs spring: application: name: my-service

2. Use Configuration Properties Classes

java
@ConfigurationProperties(prefix = "app") @Component public class AppProperties { private String name; private String version; // getters and setters }

3. Production Checklist

  • Disable debug mode: debug: false
  • Disable SQL logging: show-sql: false
  • Set appropriate log levels
  • Configure connection pool
  • Use environment variables for secrets
  • Configure health check endpoints
  • Set appropriate timeout values

Summary

FeatureDescription
File Separationapplication-{profile}.yml
Multi-documentUse --- separator
ActivationConfig, CLI, env var, JVM arg
Conditional Beans@Profile annotation
Profile Groupsspring.profiles.group
PriorityCLI > Env Var > Config File
标签:Spring Boot