How to Dynamically Refresh Spring Boot Config with @RefreshScope – Complete Guide
This guide explains why dynamic configuration refresh is essential in Spring Boot microservices, introduces the @RefreshScope annotation, walks through project setup, code implementation, endpoint usage, advanced scenarios like Spring Cloud Bus and Kubernetes, and provides best practices and troubleshooting tips.
Why dynamic refresh is needed
In traditional Spring Boot applications, changing a property file such as application.properties or application.yml requires restarting the whole JVM, which causes service interruption and is unacceptable in production environments. Dynamic refresh aims to apply configuration changes instantly without restarting the application, a requirement that becomes critical when configuration is stored in remote configuration centers like Spring Cloud Config, Nacos, Apollo, or Kubernetes ConfigMap.
What is @RefreshScope
@RefreshScopeis a special Spring Cloud annotation built on top of the standard Spring @Scope. It can be placed on @Component, @Configuration or @Bean definitions. When a refresh event is triggered, beans annotated with @RefreshScope are destroyed and lazily recreated, injecting the latest configuration values from the environment.
Project setup and step‑by‑step implementation
Add dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
</dependencies>Configure Actuator
# Custom business configuration
my.config.message=Hello, World!
my.config.number=100
# Expose the refresh endpoint
management.endpoints.web.exposure.include=health,info,refresh⚠️ Do not expose all endpoints in production; limit exposure to the required ones and secure them.
Write a refreshable bean
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
public class DynamicConfigService {
@Value("${my.config.message:Default Hello}")
private String message;
@Value("${my.config.number:0}")
private int number;
public String getConfig() {
return String.format("Message: %s, Number: %d", message, number);
}
}Create a controller to verify the bean
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
private final DynamicConfigService service;
public TestController(DynamicConfigService service) {
this.service = service;
}
@GetMapping("/config")
public String getConfig() {
return service.getConfig();
}
}Run and test
Start the application and request http://localhost:8080/config. You should see Message: Hello, World!, Number: 100.
Change the configuration in the external source (Config Server, Nacos, or Kubernetes ConfigMap).
Trigger a refresh with curl -X POST http://localhost:8080/actuator/refresh. The response lists the refreshed property keys.
Request /config again – the new values are returned without restarting the JVM.
Deep dive into the refresh mechanism
The /actuator/refresh endpoint publishes a RefreshEvent. @RefreshScope listens for this event, destroys all beans annotated with it, and marks them for lazy recreation.
On the next request, the beans are rebuilt, pulling the latest values from the Environment.
The overall flow is: destroy old bean → lazy rebuild → inject new configuration.
Best practices
Prefer @ConfigurationProperties together with @RefreshScope for type‑safe, validated configuration classes.
Secure the refresh endpoint (e.g., with Spring Security or network isolation) and avoid exposing it with a wildcard.
In a cluster, use /actuator/busrefresh (Spring Cloud Bus) to broadcast the refresh to all instances.
For Kubernetes, enable automatic reload with spring.cloud.kubernetes.reload.enabled=true and spring.cloud.kubernetes.reload.strategy=refresh.
For Nacos, set spring.cloud.nacos.config.refresh-enabled=true to push changes automatically.
Common pitfalls and troubleshooting
Ensure the bean you want to refresh is annotated with @RefreshScope.
Verify that the configuration source supports dynamic loading (Config Server, Nacos, Kubernetes).
If /refresh returns no properties, the changed keys may not be recognized; check the source and property names.
During refresh, beans are temporarily unavailable; heavy initialization (e.g., DB connections) may cause latency—add client‑side retry logic.
Values injected with @Value inside @Scheduled tasks do not update automatically; fetch values from a refreshable bean instead.
Conclusion
By following this guide you can integrate @RefreshScope into a Spring Boot + Spring Cloud stack, achieve zero‑downtime configuration updates, avoid common mistakes, and safely expose refresh endpoints in production environments.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ray's Galactic Tech
Practice together, never alone. We cover programming languages, development tools, learning methods, and pitfall notes. We simplify complex topics, guiding you from beginner to advanced. Weekly practical content—let's grow together!
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.
