Let’s say you have created a Spring Boot application and you fetch properties from application.yml file.
Every time you want to change a property you need to restart your application.
And if there are few more projects having similar configuration you need to replicate the properties in those applications as well.
To solve this , Spring provides the option of a config server.
Spring Config Server provides two major advantages:
- You have centralized configuration and so don’t have to replicate the same properties across different applications
- You don’t have to redeploy your applications for any configuration change.
Here are the steps to achieve it:
- Set up the config server.
- Set up the repository with configuration data.
- Point the config server to the repository.
- Create a client application.
- Test.
STEP1: Set up the config server
Create a Spring Boot application and add the dependency spring-cloud-config-server in pom.xml:
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
...
..
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</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>
Now add @EnableConfigServer annotation to the main class:
package app.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class ConfigserverApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigserverApplication.class, args);
}
}
The config server is ready.
There is one more thing to do .
You need to tell the config server where to look for the configuration properties.
Before that let’s set up the configuration repository.
STEP 2 – Set up configuration repository
We need to put all the configuration data somewhere.
We can very well add it to git repository and make the config server point to it.
I created a folder in my machine , put an application.yml file with a single property and committed it to github:
application.yml:
message: Hello There!
Spring config server will automatically pull all properties from application.yml and server them to all its clients.
You can also add project specific application properties in your own yaml file.
For example let’s say you have a client app named configclient.
You can create a configclient.yml in the above location and put “configclient” app specific properties there . In this case the spring.application.name property in application.yml file of the client app should have the same name “configclient“. Spring Config Server will serve those values only to “configclient” client app in this case.
STEP3: Point the config server to the repository
Once your config server and repository is ready , point the config server to the repository using the property spring.cloud.config.server.git.uri in application.yml file of config server app:
spring:
cloud:
config:
server:
git:
uri: https://github.com/vijaysrj/sampleconfig
default-label: master
Now the config server will automatically pull values from this git repository.
Also add the property “default-label” as shown above , else application will start up with errors. This is the default branch name of your github repository where the config server needs to look into.
Start the config server.
STEP 4: Create a client application
Create a spring boot application and add the dependency spring-cloud-starter-config in pom.xml:
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
</properties>
<dependencies>
...
..
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</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>
Point to the config server set up earlier using the property spring.config.import in application.yml file:
spring:
config:
import: optional:configserver:http://localhost:8082
Create a sample REST API which reads the property “message” from the application.yml file committed to github repository:
package app.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Value("${message}")
private String message;
@GetMapping("/test")
public String getValue() {
return message;
}
}
As you notice you can read the property “message” from the github repository just like you read any property from Spring Boot project’s application.yml file.
Start the client app.
That’s it!
STEP5: Test
Now let’s test the application:
The message has been read through the config server.
Now if you change the property value in your github repository it wont be automatically refreshed. To enable that follow the below steps:
- Add @RefreshScope annotation to the rest controller class
- Add Spring Boot Actuator dependency in the client pom.xml
- Modify the property file in github
- Call the endpoint /actuator/refresh of client application to refresh the values it fetched
- Hit the API again to see the modified value
- Add @RefreshScope annotation
package app.example;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope
@RestController
public class TestController {
@Value("${message}")
private String message;
@GetMapping("/test")
public String getValue() {
return message;
}
}
2.Add spring boot actuator dependency in client pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
By default the actuator end points are disabled . To enable them , add the below property in application.yml file:
management:
endpoints:
web:
exposure:
include: "*"
3. Change the property
4.Hit refresh endpoint of client app:
It is a POST request with an empty body.
5.And then hit the API :
You see the modified configuration without restarting the client app or the config server!
You just need to hit refresh API as an extra step.
That’s it!
Here are the links to the config server, configuration repository and client app:
https://github.com/vijaysrj/configserver
Leave a Reply