Allow recursive list binding when iterable source
Further refine recursive binding rules so that Lists are supported when the underlying source is iterable. Close gh-10702
This commit is contained in:
parent
5fb9162875
commit
0fbb4989da
|
|
@ -19,6 +19,7 @@ package org.springframework.boot.context.properties.bind;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
|
||||
/**
|
||||
* Internal strategy used by {@link Binder} to bind aggregates (Maps, Lists, Arrays).
|
||||
|
|
@ -31,16 +32,17 @@ abstract class AggregateBinder<T> {
|
|||
|
||||
private final BindContext context;
|
||||
|
||||
private final boolean allowRecursiveBinding;
|
||||
|
||||
AggregateBinder(BindContext context, boolean allowRecursiveBinding) {
|
||||
AggregateBinder(BindContext context) {
|
||||
this.context = context;
|
||||
this.allowRecursiveBinding = allowRecursiveBinding;
|
||||
}
|
||||
|
||||
boolean isAllowRecursiveBinding() {
|
||||
return this.allowRecursiveBinding;
|
||||
}
|
||||
/**
|
||||
* Determine if recursive binding is supported.
|
||||
* @param source the configuration property source or {@code null} for all sources.
|
||||
* @return if recursive binding is supported
|
||||
*/
|
||||
protected abstract boolean isAllowRecursiveBinding(
|
||||
ConfigurationPropertySource source);
|
||||
|
||||
/**
|
||||
* Perform binding for the aggregate.
|
||||
|
|
|
|||
|
|
@ -266,8 +266,10 @@ public class Binder {
|
|||
private <T> Object bindAggregate(ConfigurationPropertyName name, Bindable<T> target,
|
||||
BindHandler handler, Context context, AggregateBinder<?> aggregateBinder) {
|
||||
AggregateElementBinder elementBinder = (itemName, itemTarget, source) -> {
|
||||
boolean allowRecursiveBinding = aggregateBinder
|
||||
.isAllowRecursiveBinding(source);
|
||||
Supplier<?> supplier = () -> bind(itemName, itemTarget, handler, context,
|
||||
aggregateBinder.isAllowRecursiveBinding());
|
||||
allowRecursiveBinding);
|
||||
return context.withSource(source, supplier);
|
||||
};
|
||||
return context.withIncreasedDepth(
|
||||
|
|
|
|||
|
|
@ -45,7 +45,12 @@ abstract class IndexedElementsBinder<T> extends AggregateBinder<T> {
|
|||
private static final String INDEX_ZERO = "[0]";
|
||||
|
||||
IndexedElementsBinder(BindContext context) {
|
||||
super(context, false);
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowRecursiveBinding(ConfigurationPropertySource source) {
|
||||
return source == null || source instanceof IterableConfigurationPropertySource;
|
||||
}
|
||||
|
||||
protected final void bindIndexed(ConfigurationPropertyName name, Bindable<?> target,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,12 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
|||
.mapOf(String.class, String.class);
|
||||
|
||||
MapBinder(BindContext context) {
|
||||
super(context, true);
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAllowRecursiveBinding(ConfigurationPropertySource source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ public class CollectionBinderTests {
|
|||
assertThat(result.getItemsSet()).containsExactly("a", "b", "c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindToBeanWithNestedCollectionShouldPopulateCollection()
|
||||
throws Exception {
|
||||
MockConfigurationPropertySource source = new MockConfigurationPropertySource();
|
||||
|
|
|
|||
Loading…
Reference in New Issue