Skip to content

Commit

Permalink
Merge pull request #308 from dromara/dev
Browse files Browse the repository at this point in the history
[ISSUE #307] support springboot 1.x property binding
  • Loading branch information
yanhom1314 authored Jul 8, 2023
2 parents 2788040 + 9484b0b commit 4ade950
Showing 1 changed file with 64 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@

package org.dromara.dynamictp.starter.common.binder;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.dynamictp.common.properties.DtpProperties;
import org.dromara.dynamictp.core.spring.PropertiesBinder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertyResolver;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Map;

import static org.dromara.dynamictp.common.constant.DynamicTpConst.MAIN_PROPERTIES_PREFIX;
Expand All @@ -37,24 +43,77 @@
* @author yanhom
* @since 1.0.3
**/
@Slf4j
public class SpringBootPropertiesBinder implements PropertiesBinder {

@Override
public void bindDtpProperties(Map<?, Object> properties, DtpProperties dtpProperties) {
try {
Class.forName("org.springframework.boot.context.properties.bind.Binder");
doBindIn2X(properties, dtpProperties);
} catch (Exception e) {
doBindIn1X(properties, dtpProperties);
}
}

@Override
public void bindDtpProperties(Environment environment, DtpProperties dtpProperties) {
try {
Class.forName("org.springframework.boot.context.properties.bind.Binder");
doBindIn2X(environment, dtpProperties);
} catch (Exception e) {
doBindIn1X(environment, dtpProperties);
}
}

private void doBindIn2X(Map<?, Object> properties, DtpProperties dtpProperties) {
ConfigurationPropertySource sources = new MapConfigurationPropertySource(properties);
Binder binder = new Binder(sources);
ResolvableType type = ResolvableType.forClass(DtpProperties.class);
Bindable<?> target = Bindable.of(type).withExistingValue(dtpProperties);
binder.bind(MAIN_PROPERTIES_PREFIX, target);
BeanUtils.copyProperties(dtpProperties, DtpProperties.getInstance());
}

@Override
public void bindDtpProperties(Environment environment, DtpProperties dtpProperties) {
private void doBindIn2X(Environment environment, DtpProperties dtpProperties) {
Binder binder = Binder.get(environment);
ResolvableType type = ResolvableType.forClass(DtpProperties.class);
Bindable<?> target = Bindable.of(type).withExistingValue(dtpProperties);
binder.bind(MAIN_PROPERTIES_PREFIX, target);
BeanUtils.copyProperties(dtpProperties, DtpProperties.getInstance());
}

@SuppressWarnings("all")
private void doBindIn1X(Environment environment, DtpProperties dtpProperties) {
try {
// new RelaxedPropertyResolver(environment)
Class<?> resolverClass = Class.forName("org.springframework.boot.bind.RelaxedPropertyResolver");
Constructor<?> resolverConstructor = resolverClass.getDeclaredConstructor(PropertyResolver.class);
Object resolver = resolverConstructor.newInstance(environment);

// resolver.getSubProperties(MAIN_PROPERTIES_PREFIX)
// return a map of all underlying properties that start with the specified key.
// NOTE: this method can only be used if the underlying resolver is a ConfigurableEnvironment.
Method getSubPropertiesMethod = resolverClass.getDeclaredMethod("getSubProperties", String.class);
Map<?, ?> properties = (Map<?, ?>) getSubPropertiesMethod.invoke(resolver, StringUtils.EMPTY);

doBindIn1X(properties, dtpProperties);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@SuppressWarnings("all")
private void doBindIn1X(Map<?, ?> properties, DtpProperties dtpProperties) {
try {
// new RelaxedDataBinder(dtpProperties, MAIN_PROPERTIES_PREFIX)
Class<?> binderClass = Class.forName("org.springframework.boot.bind.RelaxedDataBinder");
Constructor<?> binderConstructor = binderClass.getDeclaredConstructor(Object.class, String.class);
Object binder = binderConstructor.newInstance(dtpProperties, MAIN_PROPERTIES_PREFIX);

// binder.bind(new MutablePropertyValues(properties))
Method bindMethod = binderClass.getMethod("bind", PropertyValues.class);
bindMethod.invoke(binder, new MutablePropertyValues(properties));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

0 comments on commit 4ade950

Please sign in to comment.