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.core.CollectionFactory;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.convert.ConverterNotFoundException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -57,6 +58,10 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
|||
Bindable<?> resolvedTarget = resolveTarget(target);
|
||||
for (ConfigurationPropertySource source : getContext().getSources()) {
|
||||
if (!ConfigurationPropertyName.EMPTY.equals(name)) {
|
||||
Object converted = convertIfFound(name, source, resolvedTarget);
|
||||
if (converted != null) {
|
||||
return converted;
|
||||
}
|
||||
source = source.filter(name::isAncestorOf);
|
||||
}
|
||||
new EntryBinder(name, resolvedTarget, elementBinder).bindEntries(source, map);
|
||||
|
|
@ -72,6 +77,20 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
|||
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
|
||||
protected Map<Object, Object> merge(Map<Object, Object> existing,
|
||||
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.MockConfigurationPropertySource;
|
||||
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.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -524,6 +527,29 @@ public class MapBinderTests {
|
|||
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,
|
||||
ResolvableType valueType) {
|
||||
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