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.

Ray's Galactic Tech
Ray's Galactic Tech
Ray's Galactic Tech
How to Dynamically Refresh Spring Boot Config with @RefreshScope – Complete Guide

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

@RefreshScope

is 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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring Cloud@RefreshScopespring-bootdynamic-config
Ray's Galactic Tech
Written by

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!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.