DEV Community

Salad Lam
Salad Lam

Posted on

Spring Cloud: Refresh scope bean

Properties of microservice may be changed during execution. A mechanism is available for refresh in Spring Cloud.

Following library is used

  • Java 17
  • Spring Framework 6.1.6
  • Spring Cloud Common 4.1.2

About @RefreshScope annotation

Following is the definition of @RefreshScope.

package org.springframework.cloud.context.config.annotation;
// ...
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Scope("refresh")
@Documented
public @interface RefreshScope {
  // ...
}
Enter fullscreen mode Exit fullscreen mode

@RefreshScope (or @scope("refresh")) is used for setting a bean with refresh scope. Following example is a component class annotated with @RefreshScope, for accessing URL of an API.

@Component
@RefreshScope
public class ConfigComponent {

    private String apiUrl;

    public String getApiUrl() {
        return apiUrl;
    }

    @Value("${api-url}")
    public void setApiUrl(String apiUrl) {
        this.apiUrl = apiUrl;
    }

}
Enter fullscreen mode Exit fullscreen mode

Two bean definitions are created.

  1. name "configComponent", a singleton bean which is injected to other components. This is a proxy instance.
  2. name "scopedTarget.configComponent", a refresh scope bean that is the actual instance. New instance is replaced when a refresh action is triggered.

When getApiUrl() method of "configComponent" proxy instance is called, org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept will be called and to lookup "scopedTarget.configComponent" bean in BeanFactory.

Then org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean will be called. Bean "scopedTarget.configComponent" is a refresh scope, so the new instance is saved into cache in org.springframework.cloud.context.scope.refresh.RefreshScope.

Trigger beans refresh action

A Spring Boot Actuator endpoint (/actuator/refresh) is available for trigger beans refresh action. For enables it, to add the following into configuration.

management.endpoints.web.exposure.include=refresh
Enter fullscreen mode Exit fullscreen mode

The operation is defined in org.springframework.cloud.context.refresh.ContextRefresher#refresh.

public synchronized Set<String> refresh() {
  Set<String> keys = refreshEnvironment();
  this.scope.refreshAll();
  return keys;
}
Enter fullscreen mode Exit fullscreen mode

When it is triggered, first the configuration is reloaded from configuration sources provided by such as Spring Cloud Config, Spring Cloud Kubernetes. Then, existing refresh scope beans will be dereferenced and cannot be accessed furthermore. A new bean will be created at the point the bean method is called by using values of new configuration.

Reference

  1. https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/application-context-services.html#refresh-scope

Top comments (0)