revert default value when the field is deleted in @ConfigurationProperties bean. (#681)

pull/699/head
dongyinuo 3 years ago
parent 4ebfd3128f
commit 88c7f47fb6

@ -5,3 +5,4 @@
- [Optimize/optimize annotation.](https://github.com/Tencent/spring-cloud-tencent/pull/672)
- [Optimize: Register the service with the ProviderAPI#registerInstance method.](https://github.com/Tencent/spring-cloud-tencent/pull/686)
- [docs:update PR template.](https://github.com/Tencent/spring-cloud-tencent/pull/690)
- [enhancement: revert default value when the field is deleted in @ConfigurationProperties bean](https://github.com/Tencent/spring-cloud-tencent/issues/681)

@ -18,11 +18,17 @@
package com.tencent.cloud.polaris.config.adapter;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import com.tencent.polaris.api.utils.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationPropertiesBean;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
@ -31,6 +37,8 @@ import org.springframework.cloud.context.properties.ConfigurationPropertiesRebin
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* Optimize {@link ConfigurationPropertiesRebinder}, only rebuild affected beans.
@ -39,9 +47,13 @@ import org.springframework.util.CollectionUtils;
*/
public class AffectedConfigurationPropertiesRebinder extends ConfigurationPropertiesRebinder {
private static final Logger LOGGER = LoggerFactory.getLogger(AffectedConfigurationPropertiesRebinder.class);
private ApplicationContext applicationContext;
private Map<String, ConfigurationPropertiesBean> propertiesBeans = new HashMap<>();
private final Map<String, Map<String, Object>> propertiesBeanDefaultValues = new ConcurrentHashMap<>();
public AffectedConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
super(beans);
}
@ -53,6 +65,7 @@ public class AffectedConfigurationPropertiesRebinder extends ConfigurationProper
this.applicationContext = applicationContext;
propertiesBeans = ConfigurationPropertiesBean.getAll(applicationContext);
initPropertiesBeanDefaultValues(propertiesBeans);
}
@Override
@ -75,8 +88,56 @@ public class AffectedConfigurationPropertiesRebinder extends ConfigurationProper
.toString();
if (key.startsWith(propertiesPrefix)) {
rebind(name);
rebindDefaultValue(name, key);
}
});
});
}
private void rebindDefaultValue(String beanName, String key){
String changeValue = applicationContext.getEnvironment().getProperty(key);
if (StringUtils.hasLength(changeValue)){
return;
}
Map<String, Object> defaultValues = propertiesBeanDefaultValues.get(beanName);
if (MapUtils.isEmpty(defaultValues)){
return;
}
try {
String fieldName = key.substring(key.lastIndexOf(".") + 1);
Object bean = applicationContext.getBean(beanName);
Field field = ReflectionUtils.findField(bean.getClass(), fieldName);
assert field != null;
field.setAccessible(true);
field.set(bean, defaultValues.get(fieldName));
} catch (Exception e){
LOGGER.error("[SCT Config] rebind default value error, bean = {}, key = {}", beanName, key);
}
}
private void initPropertiesBeanDefaultValues(Map<String, ConfigurationPropertiesBean> propertiesBeans){
if (MapUtils.isEmpty(propertiesBeans)){
return;
}
for (ConfigurationPropertiesBean propertiesBean : propertiesBeans.values()){
Map<String, Object> defaultValues = new HashMap<>();
try {
Object instance = propertiesBean.getInstance().getClass().getDeclaredConstructor((Class<?>[]) null).newInstance();
ReflectionUtils.doWithFields(instance.getClass(), field -> {
try {
field.setAccessible(true);
defaultValues.put(field.getName(), field.get(instance));
} catch (Exception ignored){}
}, field -> {
int modifiers = field.getModifiers();
return !Modifier.isFinal(modifiers) && !Modifier.isStatic(modifiers);
});
}catch (Exception ignored){}
propertiesBeanDefaultValues.put(propertiesBean.getName(), defaultValues);
}
}
}

Loading…
Cancel
Save