Spring Boot按需重载配置文件属性技术问询
Alright, let's tackle your requirement of on-demand loading and auto-reloading configuration properties in Spring Boot. Here's a step-by-step solution tailored to your existing setup:
1. 基础配置完善(确保@ConfigurationProperties生效)
First, let's fix a common oversight: your GetValues class needs to be a Spring-managed bean. Add the @Component annotation so Spring can scan and initialize it, along with @RefreshScope to enable refresh capability:
@Component @ConfigurationProperties @RefreshScope public class GetValues { private List<String> values; // Getters and Setters public List<String> getValues() { return values; } public void setValues(List<String> values) { this.values = values; } }
2. 手动触发配置刷新(使用Actuator端点)
The simplest way to reload properties on demand is using Spring Boot Actuator's /refresh endpoint. Here's how to set it up:
Step 2.1 添加Actuator依赖
Add the actuator starter to your build file:
Maven (pom.xml):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Gradle (build.gradle):
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Step 2.2 暴露Refresh端点
Update your application configuration (application.yml or application.properties) to expose the refresh endpoint:
management: endpoints: web: exposure: include: refresh
Step 2.3 触发刷新
Now you can reload properties by sending a POST request to http://your-app-url/actuator/refresh. You can also wrap this in your custom REST endpoint if needed:
@RestController @RequestMapping("/config") public class ConfigController { private final RefreshScope refreshScope; public ConfigController(RefreshScope refreshScope) { this.refreshScope = refreshScope; } @PostMapping("/refresh") public String triggerRefresh() { // Refresh all beans annotated with @RefreshScope refreshScope.refreshAll(); // Or refresh only the GetValues bean: refreshScope.refresh("getValues") return "Configuration reloaded successfully"; } }
3. 自动监听配置文件变更(无需手动触发)
If you want properties to reload automatically whenever test-properties.yml changes, you can use Spring's FileSystemWatcher to monitor the file. Here's how:
Step 3.1 创建文件监听配置
@Configuration public class ConfigWatcherConfig { @Value("${spring.config.location}") private String configFilePath; @Bean public FileSystemWatcher configFileWatcher() { // Parse the file path (remove "file:" prefix) String rawPath = configFilePath.replace("file:", ""); File configFile = new File(rawPath); File parentDir = configFile.getParentFile(); // Initialize watcher with polling intervals FileSystemWatcher watcher = new FileSystemWatcher(true, Duration.ofMillis(500), Duration.ofMillis(500)); watcher.addSourceDirectory(parentDir); watcher.addListener(new ConfigFileChangeListener()); watcher.start(); return watcher; } // Stop the watcher when the application shuts down @PreDestroy public void stopWatcher() throws Exception { configFileWatcher().stop(); } }
Step 3.2 创建文件变更监听器
@Component public class ConfigFileChangeListener implements FileChangeListener { private final RefreshScope refreshScope; public ConfigFileChangeListener(RefreshScope refreshScope) { this.refreshScope = refreshScope; } @Override public void onChange(FileChangeEvent event) { // Check if the changed file is your target properties file if ("test-properties.yml".equals(event.getFile().getName())) { refreshScope.refreshAll(); System.out.println("test-properties.yml updated - properties reloaded"); } } }
4. 验证配置加载
You can create a simple REST endpoint to verify the current values:
@RestController @RequestMapping("/values") public class ValuesController { private final GetValues getValues; public ValuesController(GetValues getValues) { this.getValues = getValues; } @GetMapping public List<String> getCurrentValues() { return getValues.getValues(); } }
Now, whenever you modify test-properties.yml, either send a POST to /actuator/refresh (manual) or let the file watcher trigger an auto-refresh, then call /values to see the updated list.
内容的提问来源于stack exchange,提问作者Bhagath

