Spring boot is a popular choice while developing micro services. A micro service architecture may get divided into large number of small services.
Each services can have their own application configurations placed under application’s class path. Maintaining these configuration properties becomes very hard when number of services increases.
A possible solution for this can be using a common place to handle the configuration properties. We can set up a configuration server and other services can use this configuration server for required configuration properties.
First, We need to create a configuration server. This centralized configuration server, contains configuration properties related to all other micro services.
Setting up configuration server
Let’s set up our configuration server now.
Create a spring boot application with spring-cloud-config-server dependency.
Add required dependency
Following is the pom.xml file contains required dependencies for our configuration server.
<?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 http://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>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.asb.example</groupId> <artifactId>spring-boot-config-server</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-config-server</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.SR2</spring-cloud.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </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> </plugin> </plugins> </build> </project>
Add required configuration properties
Add the following configuration properties into application.properties file.
server.port=8888 spring.profiles.active=native spring.cloud.config.server.native.search-locations=classpath:/config/simple-service/
- server.port : This is the port of configuration server.
- spring.profiles.active : Since we are using file system back end, we have to set this property value to native.
- spring.cloud.config.server.native.search-locations : This is the configuration file path(System file path, which is placed anywhere in current system).
Let’s place configuration files inside the directory pointed by the property spring.cloud.config.server.native.search-locations. In our example, we will use /src/main/resources/config directory of spring boot application.
Create a simple-service folder under /src/main/resources directory.
Create two configuration .yml files with name simple-service-dev.yml and simple-service-prod.yml.
These files should have the name with pattern applicationName-profile.yml. Our client spring boot application will have spring application name set to simple-service, with two active profiles dev and prod.
Both files contains a single configuration property my.prop with some random value.
simple-service-dev.yml
my: prop: Hello Simple Service DEVELOPMENT Environment!!!
simple-service-prod.yml
my: prop: Hello Simple service PRODUCTION Environment!!!!!
Enable configuration server by using @EnableConfigServer
Enable configuration server by using @EnableConfigServer annotation to spring boot application class.
@SpringBootApplication @EnableConfigServer public class SpringBootConfigServerApplication { public static void main(String[] args) { SpringApplication.run(SpringBootConfigServerApplication.class, args); } }
Test the configuration server
Our configuration server with file system back end is ready to launch!! Start the server by running the spring boot application.

Now we can check if configuration server is working as expected. We can access our two configuration properties by hitting respective end points.
Profile dev related configuration file is available at : http://localhost:8888/simple-service/dev.

Profile dev related configuration file is available at : http://localhost:8888/simple-service/prod.

Setting up configuration client
Our configuration server is ready. Let’s create a configuration client service now.
Add required dependency
Create a spring boot application with dependency spring-cloud-config-client. Complete pom.xml file is given below.
<?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 http://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>2.1.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.asb.example</groupId> <artifactId>simple-service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>simple-service</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <spring-cloud.version>Greenwich.SR2</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-config-client</artifactId> </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> </plugin> </plugins> </build> </project>
Create bootstrap configuration file
create a file bootstrap.properties under directory src/main/resources/ and add the following properties.
bootstrap.properties
spring.profiles.active=dev,prod spring.application.name=simple-service spring.cloud.config.url=http://localhost:8888
- spring.profiles.active : This property can be used to set active spring boot profile. We have added dev and prod in above example.
- spring.application.name : This is the spring application name. Make sure that the name should match with the configuration file name(Ex : simple-service-dev.properties)
- spring.cloud.config.url : This property points to the config server path.
Testing config clients
Modify client spring boot application class by adding a rest end point to check the configuration properties.
package com.asb.example; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class SimpleServiceApplication { @Value(value = "${my.prop}") private String myProp; @GetMapping("/") public String getMyProp() { return "Prop value: " + myProp; } public static void main(String[] args) { SpringApplication.run(SimpleServiceApplication.class, args); } }
Run the config client applications with different profiles and ports using command line arguments. Let’s use port 8080 for dev profile and 8090 for prod profile.
If you are using IDE like STS, we can run application by Right click > Run as > Run Configurations. Here, specify command line arguments under Arguments tab as shown below.

Once both the servers are started, we can access them under http://localhost:8080 for dev profile and http://localhost:8090 for prod profile.


We have accessed configuration properties from configuration server!! Good job!! 🙂 Well done!! 🙂
Detect configuration changes with @RefreshScope
What if the configuration properties change when application is running?Spring cloud configuration server exposes modified properties without requiring any changes or server restart.
Client service will not detect any changes occurred to configuration properties, as it loads configuration properties during application startup.
To detect modified configuration properties, we have to annotate configuration client service with @RefrershScope annotation. Note that only custom property value changes are detected from this annotation.
Update config client service with as shown below.
@SpringBootApplication @RestController @RefreshScope public class SimpleServiceApplication { //..... }
Also, add spring-boot-starter-actuator dependency to expose /refresh end point for client server.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
By default, this end point is not enabled in spring boot 2 applications. To enable it add following configuration property to application.properties file.
management.endpoints.web.exposure.include=refresh
Update prod profile property to inside simple-service-prod.yml file to some different value as shown below.
Make sure both config server and client service are running before modifying configuration value.
my: prop: Hello Simple service PRODUCTION Environment Updated!!!
Now access the refresh end point using postman. Refresh end point is exposed as POST end point, so we can not access it from browser.

Refresh the browser now. We should be able to get updated configuration property value. 🙂

Congratulations! We have refreshed configuration property without restarting the server. Good job! 🙂 🙂
Conclusion
In this article, we learned how to setup spring boot cloud configuration server. We also created a simple service, used as configuration client to read the property values.
We also learned how to refresh the modified configuration property values without server restart.
Source code is available on Github. Happy coding!! 🙂 🙂