I have a project in which I want to update property from application.properties in runtime, and to recreate the beans that depend on configuration and configuration bean itself with the new/updated value. Beans are destroyed when i call http://localhost:8888/actuator/refresh but the value is not updated. The steps i do :
I have tried also with @Value annotation, but no success and can't figure out the problem.
Any help would be appreciated :)
Below is the code : ConfigProperties.java
package org.example.refreshscopeworkingproject;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "demo")
@RefreshScope
public class ConfigProperties {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@PostConstruct
public void init() {
System.out.println("ConfigProperties bean created with message: " + message);
}
@PreDestroy
public void destroy() {
System.out.println("ConfigProperties destroyed");
}
}
DemoController.java
package org.example.refreshscopeworkingproject;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
@RefreshScope
public class DemoController {
private final ConfigProperties configProperties;
public DemoController(ConfigProperties configProperties) {
this.configProperties = configProperties;
}
@GetMapping("/message")
public String getMessage() {
return configProperties.getMessage();
}
@PostConstruct
public void init() {
System.out.println("Controller initialized");
}
@PreDestroy
public void destroy() {
System.out.println("Controller destroyed");
}
}
RefreshScopeWorkingProjectApplication.java
package org.example.refreshscopeworkingproject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RefreshScopeWorkingProjectApplication {
public static void main(String[] args) {
SpringApplication.run(RefreshScopeWorkingProjectApplication.class, args);
}
}
application.properties :
demo.message=Hello, RefreshScope1111!
management.endpoints.web.exposure.include=*
logging.level.org.springframework.boot.actuate=DEBUG
logging.level.org.springframework.boot.context.properties=DEBUG
server.port=8888
pom.xml :
<?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 https://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>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>RefreshScopeWorkingProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>RefreshScopeWorkingProject</name>
<description>RefreshScopeWorkingProject</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
<version>4.0.3</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
It looks like you are changing the wrong application.properties
that your application is using. When you build a project with Maven, your resources and compiled classes are placed in the target
folder. This is the folder where the application.properties
you need to change is located. If you are building the project into an executable jar file, the application.properties
will be inside this file, and you will not be able to change it. In this case, just create a new application.properties
file next to your jar file and put the desired properties with new values in it. The settings from the external file will override the settings from the internal one, and you will be able to easily change them.
For more information, see the Externalized Configuration section of the Spring Boot documentation.