diff --git a/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/AnoValueRefreshPostProcessor.java b/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/AnoValueRefreshPostProcessor.java index f7417d61..621ed2f3 100644 --- a/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/AnoValueRefreshPostProcessor.java +++ b/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/AnoValueRefreshPostProcessor.java @@ -1,7 +1,6 @@ package com.git.hui.boot.properties.value.config.dynamic; import com.alibaba.fastjson.JSONObject; -import javafx.util.Pair; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -13,10 +12,13 @@ import org.springframework.context.event.EventListener; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import org.springframework.util.PropertyPlaceholderHelper; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -27,7 +29,7 @@ */ @Component public class AnoValueRefreshPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements EnvironmentAware { - private Map mapper = new HashMap<>(); + private Map> mapper = new HashMap<>(); private Environment environment; @Override @@ -37,7 +39,7 @@ public boolean postProcessAfterInstantiation(Object bean, String beanName) throw } /** - * 扫描bean的所有属性,并获取@MetaVal修饰的属性 + * 这里主要的目的就是获取支持动态刷新的配置属性,然后缓存起来 * * @param bean */ @@ -51,8 +53,11 @@ private void processMetaValue(Object bean) { for (Field field : clz.getDeclaredFields()) { if (field.isAnnotationPresent(Value.class)) { Value val = field.getAnnotation(Value.class); - Pair pair = pickPropertyKey(val.value()); - mapper.put(pair.getKey(), new FieldPair(bean, field, val, pair.getValue())); + List keyList = pickPropertyKey(val.value(), 0); + for (String key : keyList) { + mapper.computeIfAbsent(key, (k) -> new ArrayList<>()) + .add(new FieldPair(bean, field, val.value())); + } } } } catch (Exception e) { @@ -65,25 +70,29 @@ private void processMetaValue(Object bean) { * 实现一个基础的配置文件参数动态刷新支持 * * @param value - * @return + * @return 提取key列表 */ - private Pair pickPropertyKey(String value) { - int start = value.indexOf("$") + 2; + private List pickPropertyKey(String value, int begin) { + int start = value.indexOf("${", begin) + 2; + if (start < 2) { + return new ArrayList<>(); + } + int middle = value.indexOf(":", start); int end = value.indexOf("}", start); String key; - String defaultValue; if (middle > 0 && middle < end) { // 包含默认值 key = value.substring(start, middle); - defaultValue = value.substring(middle + 1, end); } else { // 不包含默认值 key = value.substring(start, end); - defaultValue = null; } - return new Pair<>(key, defaultValue); + + List keys = pickPropertyKey(value, end); + keys.add(key); + return keys; } @Override @@ -95,26 +104,29 @@ public void setEnvironment(Environment environment) { @NoArgsConstructor @AllArgsConstructor public static class FieldPair { - private static PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}"); + private static PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}", + ":", true); Object bean; Field field; - Value value; - String defaultVal; + String value; - public void updateValue(Environment environment) throws IllegalAccessException { + public void updateValue(Environment environment) { boolean access = field.isAccessible(); if (!access) { field.setAccessible(true); } - String val = value.value(); - if (defaultVal != null) { - val = value.value().replace(":" + defaultVal, ""); + String updateVal = propertyPlaceholderHelper.replacePlaceholders(value, environment::getProperty); + try { + if (field.getType() == String.class) { + field.set(bean, updateVal); + } else { + field.set(bean, JSONObject.parseObject(updateVal, field.getType())); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); } - - String updateVal = propertyPlaceholderHelper.replacePlaceholders(val, environment::getProperty); - field.set(bean, JSONObject.parseObject(updateVal, field.getType())); field.setAccessible(access); } } @@ -135,10 +147,10 @@ public ConfigUpdateEvent(Object source, String key) { } @EventListener - public void updateConfig(ConfigUpdateEvent configUpdateEvent) throws IllegalAccessException { - FieldPair pair = mapper.get(configUpdateEvent.key); - if (pair != null) { - pair.updateValue(environment); + public void updateConfig(ConfigUpdateEvent configUpdateEvent) { + List list = mapper.get(configUpdateEvent.key); + if (!CollectionUtils.isEmpty(list)) { + list.forEach(f -> f.updateValue(environment)); } } } diff --git a/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/DynamicRest.java b/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/DynamicRest.java index 0fb6dce4..da21cdfc 100644 --- a/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/DynamicRest.java +++ b/spring-boot/002-properties-value/src/main/java/com/git/hui/boot/properties/value/config/dynamic/DynamicRest.java @@ -1,5 +1,6 @@ package com.git.hui.boot.properties.value.config.dynamic; +import com.git.hui.boot.properties.value.config.MyPropertySourcesPlaceHolderConfigure; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; @@ -10,6 +11,8 @@ import java.util.HashMap; import java.util.Map; +import static org.springframework.context.support.PropertySourcesPlaceholderConfigurer.ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME; + /** * @author yihui * @date 2021/6/7 @@ -22,6 +25,8 @@ public class DynamicRest { ConfigurableEnvironment environment; @Autowired RefreshConfigProperties refreshConfigProperties; + @Autowired + MyPropertySourcesPlaceHolderConfigure myPropertySourcesPlaceHolderConfigure; @GetMapping(path = "dynamic/update") public RefreshConfigProperties updateEnvironment(String key, String value) { @@ -41,4 +46,12 @@ public RefreshConfigProperties updateEnvironment(String key, String value) { public RefreshConfigProperties show() { return refreshConfigProperties; } + + @GetMapping(path = "dynamic/property") + public String propertyTest() { + Object obj = myPropertySourcesPlaceHolderConfigure.getAppliedPropertySources() + .get(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME).getProperty("xhh.dynamic.name"); + System.out.println(obj); + return String.valueOf(obj); + } } diff --git a/spring-boot/002-properties-value/src/test/java/com/git/hui/boot/test/PropertyPlaceHolderHelperTest.java b/spring-boot/002-properties-value/src/test/java/com/git/hui/boot/test/PropertyPlaceHolderHelperTest.java new file mode 100644 index 00000000..2b224c5f --- /dev/null +++ b/spring-boot/002-properties-value/src/test/java/com/git/hui/boot/test/PropertyPlaceHolderHelperTest.java @@ -0,0 +1,26 @@ +package com.git.hui.boot.test; + +import org.junit.Test; +import org.springframework.util.PropertyPlaceholderHelper; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author yihui + * @date 2021/6/8 + */ +public class PropertyPlaceHolderHelperTest { + + @Test + public void testPropertyHolderHelper() { + PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}", ":", true); + String template = "hello ${demo.dd:123} world!"; + + Map map = new HashMap<>(); + map.put("demo.dd", "value"); + String ans = propertyPlaceholderHelper.replacePlaceholders(template, map::get); + System.out.println(ans); + } + +}