parent
47acf8acdc
commit
41c02b307b
|
|
@ -27,6 +27,7 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyS
|
||||||
import org.springframework.boot.context.properties.source.IterableConfigurationPropertySource;
|
import org.springframework.boot.context.properties.source.IterableConfigurationPropertySource;
|
||||||
import org.springframework.core.CollectionFactory;
|
import org.springframework.core.CollectionFactory;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
import org.springframework.core.convert.ConverterNotFoundException;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -57,6 +58,10 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||||
Bindable<?> resolvedTarget = resolveTarget(target);
|
Bindable<?> resolvedTarget = resolveTarget(target);
|
||||||
for (ConfigurationPropertySource source : getContext().getSources()) {
|
for (ConfigurationPropertySource source : getContext().getSources()) {
|
||||||
if (!ConfigurationPropertyName.EMPTY.equals(name)) {
|
if (!ConfigurationPropertyName.EMPTY.equals(name)) {
|
||||||
|
Object converted = convertIfFound(name, source, resolvedTarget);
|
||||||
|
if (converted != null) {
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
source = source.filter(name::isAncestorOf);
|
source = source.filter(name::isAncestorOf);
|
||||||
}
|
}
|
||||||
new EntryBinder(name, resolvedTarget, elementBinder).bindEntries(source, map);
|
new EntryBinder(name, resolvedTarget, elementBinder).bindEntries(source, map);
|
||||||
|
|
@ -72,6 +77,20 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object convertIfFound(ConfigurationPropertyName name, ConfigurationPropertySource source, Bindable<?> target) {
|
||||||
|
ConfigurationProperty configurationProperty = source.getConfigurationProperty(name);
|
||||||
|
if (configurationProperty != null) {
|
||||||
|
try {
|
||||||
|
return ResolvableTypeDescriptor.forType(target.getType())
|
||||||
|
.convert(getContext().getConversionService(), configurationProperty.getValue());
|
||||||
|
}
|
||||||
|
catch (ConverterNotFoundException ex) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<Object, Object> merge(Map<Object, Object> existing,
|
protected Map<Object, Object> merge(Map<Object, Object> existing,
|
||||||
Map<Object, Object> additional) {
|
Map<Object, Object> additional) {
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,11 @@ import org.springframework.boot.context.properties.source.ConfigurationPropertyS
|
||||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||||
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
import org.springframework.boot.context.properties.source.MockConfigurationPropertySource;
|
||||||
import org.springframework.core.ResolvableType;
|
import org.springframework.core.ResolvableType;
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.core.env.StandardEnvironment;
|
||||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
|
@ -524,6 +527,29 @@ public class MapBinderTests {
|
||||||
assertThat(foo.get().getFoos().get("foo2").getValue()).isEqualTo("three");
|
assertThat(foo.get().getFoos().get("foo2").getValue()).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindToMapWithCustomConverter() {
|
||||||
|
DefaultConversionService conversionService = new DefaultConversionService();
|
||||||
|
conversionService.addConverter(new MapConverter());
|
||||||
|
Binder binder = new Binder(this.sources, null, conversionService);
|
||||||
|
|
||||||
|
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||||
|
source.put("foo", "a,b");
|
||||||
|
this.sources.add(source);
|
||||||
|
Map<String, String> map = binder.bind("foo", STRING_STRING_MAP).get();
|
||||||
|
assertThat(map.get("a")).isNotNull();
|
||||||
|
assertThat(map.get("b")).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bindToMapWithNoConverterForValue() {
|
||||||
|
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||||
|
source.put("foo", "a,b");
|
||||||
|
this.sources.add(source);
|
||||||
|
BindResult<Map<String, String>> result = this.binder.bind("foo", STRING_STRING_MAP);
|
||||||
|
assertThat(result.isBound()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
private <K, V> Bindable<Map<K, V>> getMapBindable(Class<K> keyGeneric,
|
private <K, V> Bindable<Map<K, V>> getMapBindable(Class<K> keyGeneric,
|
||||||
ResolvableType valueType) {
|
ResolvableType valueType) {
|
||||||
ResolvableType keyType = ResolvableType.forClass(keyGeneric);
|
ResolvableType keyType = ResolvableType.forClass(keyGeneric);
|
||||||
|
|
@ -576,4 +602,13 @@ public class MapBinderTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class MapConverter implements Converter<String, Map<String, String>> {
|
||||||
|
@Override
|
||||||
|
public Map<String, String> convert(String s) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
StringUtils.commaDelimitedListToSet(s).forEach(k -> map.put(k, ""));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue