11 de setembro de 2026 • Java

31 - Spring Cloud Config

1. Introduction

In a real-world Spring Boot application, configuration is usually not limited to a single application.properties or application.yml file.

As the number of microservices grows, configuration becomes difficult to manage:

  • Multiple microservices
  • Multiple environments
  • Different database configurations
  • Different API URLs
  • Different credentials
  • Feature flags
  • Environment-specific properties
  • Configuration changes without redeploying applications

Spring Cloud Config provides a centralized configuration management solution for distributed systems.

The main idea is:

Store configuration in one centralized location and allow multiple microservices to retrieve their configuration from a Config Server.


2. Real-World Project Problems

Imagine a company has the following microservices:

user-service
order-service
payment-service
notification-service

Each service has its own configuration.

For example:

user-service
    database.url
    database.username
    jwt.expiration

order-service
    database.url
    payment-service.url
    order.timeout

payment-service
    stripe.api.url
    stripe.api.key
    payment.timeout

Now imagine the application is deployed into three environments:

Development
QA
Production

Each environment requires different configuration.

Without centralized configuration, we may end up with:

user-service
    application-dev.yml
    application-qa.yml
    application-prod.yml

order-service
    application-dev.yml
    application-qa.yml
    application-prod.yml

payment-service
    application-dev.yml
    application-qa.yml
    application-prod.yml

This creates several problems.

Problems

1. Configuration duplication

The same configuration may be duplicated across multiple services.

2. Configuration inconsistency

One service may use:

payment-service.url=http://payment-service:8080

while another service accidentally uses:

payment-service.url=http://payment-service:8081

3. Configuration changes require redeployment

Suppose the following property changes:

order.timeout=30

If the property is packaged inside the application, we may need to:

Change configuration

Build application

Create Docker image

Deploy application

Restart service

This is inconvenient for configuration-only changes.

4. Managing multiple environments

Production, QA and development require different configurations.

Managing all of these independently becomes difficult.

5. Configuration management

Configuration should ideally be:

  • Centralized
  • Version controlled
  • Environment aware
  • Easily changeable
  • Consistent across services

This is where Spring Cloud Config helps.


3. What is Spring Cloud Config?

Spring Cloud Config provides server-side and client-side support for externalized configuration in distributed systems.

It follows a centralized configuration architecture.

Instead of every microservice managing its configuration independently:

Microservice

Local configuration

we can have:

Git Repository

Config Server

Microservices

The Config Server acts as a centralized configuration provider.


4. Spring Cloud Config Architecture

A typical architecture looks like this:

┌─────────────────────┐
│   Git Repository    │
│                     │
│ application.yml     │
│ user-service.yml    │
│ order-service.yml   │
│ payment-service.yml │
└──────────┬──────────┘

           │ Configuration

┌─────────────────────┐
│    Config Server    │
│   Spring Boot App   │
└──────────┬──────────┘

    ┌──────┼───────┐
    │      │       │
    ↓      ↓       ↓
User     Order   Payment
Service  Service Service

The components are:

Config Repository

Usually a Git repository containing configuration files.

Config Server

A Spring Boot application responsible for retrieving configuration from the repository.

Config Clients

Microservices that request configuration from the Config Server.


5. Configuration Repository

A common Git repository structure could be:

config-repo/

├── application.yml
├── user-service.yml
├── order-service.yml
├── payment-service.yml

├── user-service-dev.yml
├── user-service-prod.yml

├── order-service-dev.yml
└── order-service-prod.yml

The naming convention is important.

For example:

user-service.yml

contains common configuration for user-service.

And:

user-service-prod.yml

contains production-specific configuration.


6. Configuration File Naming Convention

Spring Cloud Config commonly follows this structure:

{application}-{profile}.yml

For example:

user-service-dev.yml

means:

application = user-service
profile = dev

Another example:

order-service-prod.yml

means:

application = order-service
profile = prod

There can also be a default configuration:

application.yml

This configuration can be shared by multiple services.


7. Example Configuration Repository

application.yml

company:
  name: MyCompany

logging:
  level:
    root: INFO

user-service.yml

server:
  port: 8081

user:
  max-login-attempts: 5

user-service-dev.yml

database:
  url: jdbc:mysql://localhost:3306/userdb

user-service-prod.yml

database:
  url: jdbc:mysql://production-db:3306/userdb

The same microservice can receive different configuration depending on the active profile.


8. Config Server

The Config Server is a Spring Boot application responsible for exposing configuration to clients.

The architecture becomes:

Git

Config Server

Config Client

The Config Server reads configuration from Git and exposes it through HTTP endpoints.


9. Creating the Config Server

Create a Spring Boot project.

Typical dependencies:

Spring Web
Config Server

The main application class needs the Config Server annotation.

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(
            ConfigServerApplication.class,
            args
        );
    }
}

The important annotation is:

@EnableConfigServer

This enables Spring Cloud Config Server functionality.


10. Config Server Configuration

The Config Server needs to know where the configuration repository is located.

For example:

server:
  port: 8888

spring:
  application:
    name: config-server

  cloud:
    config:
      server:
        git:
          uri: https://github.com/company/config-repo

The Config Server runs on:

http://localhost:8888

11. Git-Based Configuration

Using Git provides several important advantages.

Configuration becomes:

Version Controlled

Auditable

Reversible

Centrally Managed

For example:

Commit 1
database.url = database-v1

Commit 2
database.url = database-v2

If a configuration change causes a problem, Git allows the team to identify or revert the change.


12. Config Server API

The Config Server exposes configuration through HTTP.

For example:

GET /user-service/dev

The request means:

Application = user-service
Profile = dev

The Config Server retrieves the appropriate configuration and returns it to the client.

Another example:

GET /order-service/prod

means:

Application = order-service
Profile = prod

13. Config Client

A microservice that consumes configuration from the Config Server is called a Config Client.

For example:

user-service

can become a Config Client.

The architecture becomes:

user-service
      |
      | Request configuration

Config Server
      |

Git Repository

14. Config Client Implementation

The client application needs the appropriate Spring Cloud Config Client dependency.

The service needs to know where the Config Server is located.

A modern Spring Boot / Spring Cloud setup commonly uses:

spring:
  config:
    import: optional:configserver:http://localhost:8888

The client will contact:

http://localhost:8888

and retrieve its configuration.


15. Client Application Name

The Config Server needs to know which configuration belongs to the client.

For example:

spring:
  application:
    name: user-service

If the active profile is:

dev

the client will request configuration associated with:

user-service
dev

The Config Server can therefore load:

application.yml
user-service.yml
user-service-dev.yml

and combine the applicable properties.


16. Client Profile

The client can specify an active profile.

spring:
  application:
    name: user-service

  profiles:
    active: dev

Now the application is effectively requesting:

user-service + dev

from the Config Server.


17. Complete Config Client Example

A client application might have:

spring:
  application:
    name: user-service

  profiles:
    active: dev

  config:
    import: optional:configserver:http://localhost:8888

The Config Server:

http://localhost:8888

will provide configuration from the Git repository.


18. Reading Configuration in the Application

Suppose the Git repository contains:

user:
  max-login-attempts: 5

The Spring Boot application can read the value using @Value.

@Value("${user.max-login-attempts}")
private int maxLoginAttempts;

The application receives the value from the centralized configuration.


19. Using @ConfigurationProperties

For larger configurations, @ConfigurationProperties is often preferable.

Example:

@ConfigurationProperties(prefix = "user")
public class UserProperties {

    private int maxLoginAttempts;

    public int getMaxLoginAttempts() {
        return maxLoginAttempts;
    }

    public void setMaxLoginAttempts(int maxLoginAttempts) {
        this.maxLoginAttempts = maxLoginAttempts;
    }
}

Now configuration can be grouped into a dedicated object.

Example configuration:

user:
  max-login-attempts: 5

This approach becomes easier to maintain when many related properties exist.


20. Environment-Specific Configuration

One of the biggest benefits of Config Server is environment separation.

For example:

user-service-dev.yml

database:
  url: jdbc:mysql://localhost:3306/userdb

And:

user-service-prod.yml

database:
  url: jdbc:mysql://prod-db:3306/userdb

The application code remains the same.

Only the configuration changes.

Architecture:

Same Application

      ├── DEV → dev configuration

      ├── QA  → qa configuration

      └── PROD → prod configuration

21. Centralized Configuration Flow

The complete startup flow can be represented as:

User Service starts

Reads application name

Reads active profile

Contacts Config Server

Config Server contacts Git

Git returns configuration

Config Server returns configuration

User Service loads properties

Application starts

This allows the application configuration to be externalized.


22. Refreshing Configuration at Runtime

One common problem is:

What happens if configuration changes while the application is running?

For example:

order.timeout=30

The value changes in Git:

order.timeout=60

The application may still have the old value in memory.

We want to refresh the configuration without restarting the entire application.

Spring Boot Actuator can help expose a refresh endpoint.


23. Spring Boot Actuator

Add the Spring Boot Actuator dependency.

The Actuator provides management endpoints such as:

/actuator/health
/actuator/info
/actuator/metrics
/actuator/refresh

For refresh functionality, the /actuator/refresh endpoint is particularly important.


24. Exposing the Refresh Endpoint

The client application can configure Actuator:

management:
  endpoints:
    web:
      exposure:
        include: refresh

Now the refresh endpoint can be accessed through:

POST /actuator/refresh

Important:

The endpoint should normally be protected with authentication and authorization.

Never expose sensitive management endpoints publicly without appropriate security controls.


25. @RefreshScope

A bean whose configuration should be refreshed dynamically can use:

@RefreshScope

Example:

@RefreshScope
@RestController
public class ConfigController {

    @Value("${message}")
    private String message;

    @GetMapping("/message")
    public String getMessage() {
        return message;
    }
}

The @RefreshScope annotation allows the bean to be recreated when a refresh occurs.


26. Runtime Refresh Flow

Suppose Git contains:

message=Hello

The application starts.

The endpoint returns:

Hello

Now change Git:

message=Hello from Config Server

The application is still running.

Execute:

POST /actuator/refresh

The configuration is refreshed.

The endpoint can now return:

Hello from Config Server

No complete application restart is required.


27. Important Refresh Concept

The refresh process can be summarized as:

Git configuration changes

   Config Server

Client requests refresh

   /actuator/refresh

Environment updated

  @RefreshScope beans
    recreated

  New configuration
     becomes active

28. Configuration Refresh Limitations

Not every configuration change should automatically be considered safe to refresh.

Some properties may require:

  • Application restart
  • Connection recreation
  • Bean recreation
  • Infrastructure changes
  • Additional application logic

For example:

database connection configuration

may require more consideration than:

feature.enabled=true

Therefore, runtime refresh should be designed carefully.


29. Security Considerations

Configuration can contain sensitive information such as:

database.password
api.key
client.secret
OAuth credentials

Therefore, storing secrets directly in a public Git repository is dangerous.

In production, sensitive configuration should generally be handled using appropriate secret-management solutions such as:

HashiCorp Vault
AWS Secrets Manager
Azure Key Vault
Kubernetes Secrets

Spring Cloud Config should not be treated as a replacement for a dedicated secrets-management system.


30. Spring Cloud Config vs Local Configuration

Without Config Server

Service A → application.yml
Service B → application.yml
Service C → application.yml

Configuration is distributed across applications.

With Config Server

Git Repository

Config Server

┌─────┼─────┐
↓     ↓     ↓
A     B     C

Configuration is centralized.


31. Benefits

Spring Cloud Config provides:

  • Centralized configuration
  • Environment-specific configuration
  • Git-based version control
  • Configuration history
  • Easier configuration management
  • Externalized configuration
  • Runtime refresh support
  • Consistent configuration across microservices

32. Potential Drawbacks

There are also trade-offs.

Config Server becomes infrastructure

If clients depend on Config Server during startup, the availability of the Config Server becomes important.

Additional complexity

The architecture now includes:

Git
Config Server
Config Clients

Security

Configuration endpoints must be protected.

Secrets

Sensitive values need proper secret-management strategies.

Compatibility

Spring Boot and Spring Cloud versions must be compatible.


33. Real-World Architecture

A production architecture could look like:

┌─────────────────────────┐
│       Git Repository    │
│                         │
│ application.yml         │
│ user-service.yml        │
│ order-service.yml       │
│ payment-service.yml     │
└────────────┬────────────┘


┌─────────────────────────┐
│      Config Server      │
│                         │
│ Spring Cloud Config     │
└────────────┬────────────┘

    ┌────────┼────────┐
    │        │        │
    ↓        ↓        ↓
User      Order    Payment
Service   Service  Service
    │        │        │
    └────────┼────────┘

       Spring Actuator


      Refresh Configuration

34. Complete Example

Config Repository

application.yml

company:
  name: MyCompany

user-service.yml

user:
  max-login-attempts: 5

user-service-dev.yml

message: Hello from DEV

user-service-prod.yml

message: Hello from PROD

Config Server

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(
            ConfigServerApplication.class,
            args
        );
    }
}

Configuration:

server:
  port: 8888

spring:
  application:
    name: config-server

  cloud:
    config:
      server:
        git:
          uri: https://github.com/company/config-repo

Config Client

spring:
  application:
    name: user-service

  profiles:
    active: dev

  config:
    import: optional:configserver:http://localhost:8888

The client retrieves:

user-service.yml
user-service-dev.yml
application.yml

from the Config Server.


Dynamic Configuration

@RefreshScope
@RestController
public class MessageController {

    @Value("${message}")
    private String message;

    @GetMapping("/message")
    public String message() {
        return message;
    }
}

Actuator configuration:

management:
  endpoints:
    web:
      exposure:
        include: refresh

Then:

POST /actuator/refresh

causes refreshable configuration to be reloaded.


35. Interview Questions

What is Spring Cloud Config?

Spring Cloud Config provides centralized externalized configuration management for distributed applications and microservices.

Why use Config Server?

To centralize configuration and avoid duplicating configuration across multiple microservices and environments.

Where can configuration be stored?

Commonly in a Git repository, but other backends can also be supported.

What is a Config Client?

A microservice that retrieves its configuration from the Config Server.

What does @EnableConfigServer do?

It enables the Spring Cloud Config Server functionality in a Spring Boot application.

What is @RefreshScope?

It allows a bean to be recreated when configuration is refreshed.

How can configuration be refreshed?

A client can use the Actuator refresh endpoint:

POST /actuator/refresh

Does Spring Cloud Config replace a secret manager?

No. Sensitive secrets should generally be managed using a dedicated secret-management solution.

Why use Git with Config Server?

Git provides version control, history, auditing and the ability to revert configuration changes.


36. Key Takeaways

Spring Cloud Config solves a common microservices problem:

How do we centrally manage configuration for many applications and environments?

The architecture is:

Git Repository

Config Server

Config Clients

The Config Server centralizes configuration.

The Config Client consumes the configuration.

Spring Boot Actuator can expose:

/actuator/refresh

to trigger configuration refresh.

@RefreshScope allows selected beans to use refreshed configuration without requiring a complete application restart.

The overall idea is:

Centralize

Version Control

Externalize

Consume

Refresh
← Voltar para o blog