Dynamic Configuration in Spring Boot: Comparing Nacos, Config+Bus, and Apollo
This article explains why dynamic configuration is needed for Spring Boot applications, compares three mainstream microservice configuration centers (Nacos, Config+Bus, Apollo), and provides step‑by‑step tutorials for two Spring Boot‑specific solutions with complete code examples.
For microservices, externalizing configuration is essential to avoid restarting services for every change; the same need can arise in monolithic Spring Boot applications in scenarios such as adding data sources or handling fixed integrations with varying code segments.
The three most widely used configuration‑center solutions are Nacos (which also replaces Eureka and Config+Bus), Config+Bus (often backed by a Git repository), and Apollo (open‑sourced by Ctrip). All can be integrated with Spring Boot, but they may be heavyweight for a single service.
Spring Boot + Nacos (not recommended) – Nacos provides a management console at http://localhost:8848 , requires adding the nacos-config-spring-boot-starter dependency, and using @NacosPropertySource and @NacosValue annotations. This approach works but adds an extra Nacos server, which is overkill for a monolith.
Spring Boot + Config + Actuator (recommended) – This lightweight solution uses Spring Cloud Config and the Actuator endpoint. The required Maven dependencies are:
<!-- springCloud dependency -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- config dependency -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- actuator dependency -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>Expose all actuator endpoints with management.endpoints.web.exposure.include=* and add three custom properties:
config.version=22
config.app.name=dynamic-project
config.platform=mysqlAnnotate a controller with @RefreshScope and inject the properties using @Value :
@RestController
//@RefreshScope is required for dynamic refresh
@RefreshScope
public class DynamicConfigController {
@Value("${config.version}")
private String version;
@Value("${config.app.name}")
private String appName;
@Value("${config.platform}")
private String platform;
@GetMapping("/show/version")
public String test() {
return "version="+version+"-appName="+appName+"-platform="+platform;
}
}After starting the application, the endpoint http://localhost:8080/show/version returns the current values. Changing the properties in the target directory and invoking POST http://localhost:8080/actuator/refresh updates the values without restarting.
To avoid the manual refresh step, a custom refresh API can be added that updates the Environment programmatically and calls ContextRefresher.refresh() asynchronously:
@GetMapping("/show/refresh")
public String refresh() {
HashMap
map = new HashMap<>();
map.put("config.version", 99);
map.put("config.app.name", "appName");
map.put("config.platform", "ORACLE");
MapPropertySource propertySource = new MapPropertySource("dynamic", map);
environment.getPropertySources().addFirst(propertySource);
new Thread(() -> contextRefresher.refresh()).start();
return "success";
}This approach demonstrates how a monolithic Spring Boot application can achieve dynamic configuration refresh similar to microservice setups, using only the lightweight Config+Actuator stack.
Summary – The article walks through the motivation for externalized configuration, compares three major configuration‑center products, and provides two concrete Spring Boot implementations, ultimately recommending the simple Config+Actuator solution for single‑service projects.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.