Dynamic Configuration Updates with Spring Cloud Config
Last Updated :
27 Aug, 2024
In a microservices architecture, managing configuration properties across multiple services can become challenging, especially when these configurations need to be updated frequently. Spring Cloud Config provides a centralized configuration management solution, allowing you to manage external properties for applications across all environments. One of the key features of Spring Cloud Config is its ability to dynamically update configurations without the need to restart services.
This article will guide you through the process of setting up dynamic configuration updates with Spring Cloud Config. We will explore how to create a Spring Cloud Config Server, connect it with a client application, and demonstrate how configuration changes can be dynamically applied to a Spring Boot application.
Spring Cloud Config Server
Spring Cloud Config Server provides a centralized configuration service that is distributed and versioned, with support for dynamic updates. It typically fetches configurations from a Git repository and serves them to client applications.
Dynamic Configuration Updates
To enable dynamic updates, Spring Cloud integrates with Spring Cloud Bus, which provides a simple way to refresh configurations across multiple instances of microservices. When a configuration is updated in the Git repository, the Config Server detects the changes, and Spring Cloud Bus triggers a refresh event across all connected clients.
Key Features:
- Centralized Configuration Management: Allows you to manage configuration properties for all microservices from a single location, simplifying configuration management in complex environments.
- Dynamic Configuration Updates: Spring Cloud Config can dynamically update configuration properties without requiring client applications to restart, achieved through integration with Spring Cloud Bus.
- Versioned and Distributed Configuration: Configurations managed by Spring Cloud Config are stored in a version control system like Git, providing versioning and rollback capabilities to track changes and revert to previous configurations if necessary.
- Environment-Specific Configurations: Spring Cloud Config supports environment-specific configurations, allowing you to define configurations for development, staging, and production environments. The appropriate configuration is automatically selected based on the active profile.
- Secure Configuration: Sensitive data, such as passwords and API keys, can be encrypted and stored securely in configuration files, with built-in support for encryption and decryption of configuration properties.
- Scalability: Spring Cloud Config is designed to work in large, distributed environments, ensuring that configuration updates scale to many microservices across multiple environments and data centers.
Implementation of Dynamic Configuration Updates with Spring Cloud Config in a Spring Boot Project
Step 1: Create the Git Repository
Create a Git repository to store configuration files. For example, create an application.yml
file with the following configuration:
Message: Default Message
Step 2: Setup the Config Server
2.1: Create a New Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA with the following options:
- Name: config-server
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
2.2: Add Dependencies
Add the following dependencies into the Spring Boot project.
Project Structure
Once the project creation done, the file structure will look like the below image.
2.3: Configure Application Properties
Rename application.properties
to application.yml
and add the following configuration:
spring:
cloud:
config:
server:
git:
uri: https://github.com/iammahesh123/config-repo
clone-on-start: true
server:
port: 8888
- The
uri
specifies the location of the Git repository containing the configuration files. clone-on-start
ensures that the repository is cloned every time the server starts, ensuring the latest configurations are loaded.
2.4: Main Class
This is the entry point of the application. Add the @EnableConfigServer
annotation to enable the Config Server functionality.
Java
package com.gfg.configserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer // Enables Config Server functionality
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args); // Starts the Config Server application
}
}
- The
@EnableConfigServer
annotation activates the Config Server in the Spring Boot application. SpringApplication.run
starts the application.
pom.xml file:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>config-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>config-server</name>
<description>config-server</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.5: Run the Application
Run the application. It will start and listen on port 8888
.
Step 3: Setup the Client Application
3.1: Create a New Spring Boot Project
Create a new Spring Boot project using IntelliJ IDEA with the following options:
- Name: client-application
- Language: Java
- Type: Maven
- Packaging: Jar
Click on the Next button.
3.2: Add Dependencies
Add the following dependencies into the Spring Boot project.
Project Structure
Once the project is created, then the file structure will look like the below image.
spring-boot-starter-actuator
is included to monitor and manage the application.spring-boot-starter-web
sets up a web application, while lombok
and spring-boot-starter-test
provide code reduction and testing support.
3.3: Configure Application Properties
Rename application.properties
to application.yml
and add the following configuration:
spring:
cloud:
config:
uri: http://localhost:8888
The uri
specifies the location of the Config Server.
3.4: Create the MessageController
Class
Create a new class MessageController.java
in the com.gfg.clientapplication
package to handle incoming HTTP requests.
Java
package com.gfg.clientapplication;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // Indicates that this class is a REST controller
public class MessageController {
@Value("${message:Default message}") // Injects the 'message' property from the configuration
private String message;
@GetMapping("/message") // Maps HTTP GET requests to /message
public String getMessage() {
return this.message; // Returns the current value of the 'message' property
}
}
@RestController
marks the class as a REST controller.- The
@Value
annotation injects the message
property from the configuration, and @GetMapping
maps the /message
endpoint to the getMessage
method.
3.5: Main Class
No changes are required in the main class, but for reference:
Java
package com.gfg.clientapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // Indicates this is a Spring Boot application
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args); // Starts the Client application
}
}
pom.xml file:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>client-application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>client-application</name>
<description>client-application</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2023.0.3</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
3.6: Run the Application
Now run the application, and it will start at port 8080.
Step 4: Testing the Endpoint
test the /message
endpoint by sending a GET request to http://localhost:8080/message
. It will return the default message from the configuration.
GET http://localhost:8080/message
Output:
Updating the Application Properties in GitHub
To see dynamic updates in action, update the message
property in your GitHub repository to something like:
Message: Hello from Spring Cloud Config!
Then, you can trigger the refresh event and verify that the client application reflects the updated configuration without a restart.
Again, run the endpoint,
GET http://localhost:8080/message
Output:
This example project demonstrates the dynamic configuration with Spring Cloud Config of Spring Boot Project.
Similar Reads
Implementing Configuration Versioning with Spring Cloud Config
Configuration versioning is the critical aspect of maintaining and managing the configurations in the microservices architecture. It can allow the teams to track the changes, revert to previous versions and manage the configurations more efficiently, Spring Cloud Config can provide a powerful way to
5 min read
Using Native Configuration in Spring Cloud Config Server
Spring Cloud Config provides both server-side and client-side support for externalized configuration in distributed systems. The Config Server centralizes management of configuration properties for applications across various environments. By default, Spring Cloud Config uses Git for storage, but it
5 min read
Managing Configuration for Microservices with Spring Cloud Config
Spring Cloud Config provides the centralized external configuration management system and it is designed to work well with modern microservices architectures. It is the part of larger Spring Config suite of the tools that aim to help the developers built the cloud-native applications. Spring Cloud C
4 min read
Configuring Spring MVC with XML and Java Config
Spring MVC (Model-View-Controller) is a web framework within the Spring Framework that enables the development of web applications following the MVC design pattern. It separates application logic into three components: Model, View, and Controller, making it easier to maintain, test, and scale.Spring
6 min read
Encrypting Sensitive Configuration Data in Spring Cloud Config
Encrypting sensitive configuration data in Spring Cloud Config is essential for securing information like passwords, API keys, and other credentials. This extra layer of protection is crucial because it helps prevent unauthorized access and ensures that sensitive data remains safe, even if the confi
4 min read
Customizing the Configuration Location in Spring Cloud Config Server
Spring Cloud Config provides both server and client-side support for externalized configuration in distributed systems. The Config Server manages configuration properties for applications across various environments, allowing them to retrieve their configuration from a central location. By default,
5 min read
Spring @Configuration Annotation with Example
The @Configuration annotation in Spring is one of the most important annotations. It indicates that a class contains @Bean definition methods, which the Spring container can process to generate Spring Beans for use in the application. This annotation is part of the Spring Core framework. Let's under
4 min read
Spring Boot - Cloud Configuration Server
In microservices, we have several different services responsible for different functionalities. These services act like smaller application modules, which together form the application. Each of these modules has its own responsibility, based on the business logic of the application being built. Thes
10 min read
Spring Boot - Externalized Configuration
In Spring Boot, externalized configuration is a feature that allows you to separate configuration settings from your code. This means you can change how your application behaves by modifying configuration files without needing to recompile or redeploy the application. Spring Boot supports various co
4 min read
Configuring a Hikari Connection Pool with Spring Boot
Hikari Connection Pool with Spring Boot mainly involves setting up a high-performance database connection pool for efficient management of the database connections within the application. When developing Spring Boot applications, the application will interact with databases, managing database connec
2 min read