feat: 动态更新配置项

This commit is contained in:
骑着蜗牛追导弹 2024-12-07 05:52:18 +08:00
parent 767c710e84
commit 7b0652e8e7
3 changed files with 70 additions and 16 deletions

View File

@ -0,0 +1,63 @@
package cn.odboy.config.context;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class ValueAnnotationBeanPostProcessor implements BeanPostProcessor {
private final Logger logger = LoggerFactory.getLogger(ValueAnnotationBeanPostProcessor.class);
private final Map<String, Field> nameFieldMap = new HashMap<>();
private final Map<String, Object> nameBeanMap = new HashMap<>();
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class<?> clazz = bean.getClass();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Value.class)) {
field.setAccessible(true);
// @Value的处理
Value annotation = field.getAnnotation(Value.class);
String propertyName = annotation.value();
String substring =
propertyName.substring(propertyName.indexOf("${") + 2, propertyName.lastIndexOf("}"));
// 处理带有默认值的配置
propertyName = substring;
if (substring.contains(":")) {
String[] splits = substring.split(":");
if (splits.length == 2) {
propertyName = splits[0];
}
}
nameFieldMap.put(propertyName, field);
nameBeanMap.put(propertyName, bean);
}
}
clazz = clazz.getSuperclass();
}
return bean;
}
public void setValue(String propertyName, Object value) {
try {
Field field = nameFieldMap.getOrDefault(propertyName, null);
if (field != null) {
field.setAccessible(true);
field.set(nameBeanMap.get(propertyName), value);
}
} catch (IllegalAccessException e) {
logger.error("配置 {} 字段值 {} 失败", propertyName, value, e);
}
}
public Map<String, Field> getNameFieldMap() {
return nameFieldMap;
}
}

View File

@ -43,7 +43,7 @@ public class ConfigClient {
private static volatile ConfigClient instance; private static volatile ConfigClient instance;
/** 最大重试次数 */ /** 最大重试次数 */
private static final int MAX_RETRY_COUNT = 5; private static final int MAX_RETRY_COUNT = 2;
/** 当前重试次数 */ /** 当前重试次数 */
private static int retryCount = 0; private static int retryCount = 0;

View File

@ -1,11 +1,8 @@
package cn.odboy.rest; package cn.odboy.rest;
import java.util.HashMap; import cn.odboy.config.context.ValueAnnotationBeanPostProcessor;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -23,21 +20,15 @@ public class DemoController {
@Value("${kenaito.config-center.demo:123}") @Value("${kenaito.config-center.demo:123}")
private String demoStr; private String demoStr;
@Autowired private ConfigurableEnvironment environment; @Autowired private ValueAnnotationBeanPostProcessor valueAnnotationBeanPostProcessor;
/** 配置变化了 */ /** 配置变化了 */
@GetMapping("/test") @GetMapping("/test")
public ResponseEntity<Object> test() { public ResponseEntity<Object> test() {
String key = "kenaito.config-center.demo"; System.err.println("demoStr=" + demoStr);
String property = environment.getProperty(key); String propertyName = "kenaito.config-center.demo";
System.err.println("property=" + property); valueAnnotationBeanPostProcessor.setValue(propertyName, "xxxxxxxxxx");
Map<String, Object> properties = new HashMap<>(); System.err.println("demoStr=" + demoStr);
properties.put(key, "Hello World!");
MapPropertySource propertySource = new MapPropertySource("dynamicProperties", properties);
// 将新的属性源添加到 ConfigurableEnvironment
environment.getPropertySources().addFirst(propertySource);
String property1 = environment.getProperty(key);
System.err.println("property1=" + property1);
return ResponseEntity.ok("success"); return ResponseEntity.ok("success");
} }
} }