Spring Cloud Config provides server-side and client-side support for externalized configuration, allowing you to manage config across all environments from a central location.

Config Server

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
  
  @SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication { }
  
  # config-server application.yml
server:
  port: 8888
spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/myorg/config-repo
          default-label: main
          search-paths: '{application}'
  

Git repo structure:

  config-repo/
├── order-service/
│   ├── application.yml
│   ├── application-dev.yml
│   └── application-prod.yml
└── user-service/
    └── application.yml
  

Config Client

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  
  # bootstrap.yml (loaded before application.yml)
spring:
  application:
    name: order-service
  cloud:
    config:
      uri: http://config-server:8888
      profile: prod
      label: main
  
  @RestController
@RefreshScope  // allows runtime refresh
public class ConfigController {
    @Value("${app.feature.enabled:false}")
    private boolean featureEnabled;

    @GetMapping("/feature")
    public boolean isFeatureEnabled() {
        return featureEnabled;
    }
}
  

Refresh Configuration

After updating config in Git:

  curl -X POST http://order-service:8080/actuator/refresh
# or broadcast via Spring Cloud Bus + RabbitMQ
curl -X POST http://config-server:8888/actuator/bus-refresh
  

Encryption

Encrypt sensitive values:

  curl http://config-server:8888/encrypt -d 'mysecretpassword'
# Returns: {cipher}AQA7...
  

Store in Git:

  spring:
  datasource:
    password: '{cipher}AQA7...'
  

Best Practices

  • Store config in Git for version control and audit trail
  • Use {application}-{profile}.yml naming convention
  • Encrypt secrets with {cipher} prefix
  • Use @RefreshScope for beans that need runtime config updates
  • Never commit plaintext secrets to Git