diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java index c092448465..b88e03c906 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java @@ -25,8 +25,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; import org.springframework.beans.PropertyEditorRegistry; @@ -360,7 +362,8 @@ public class Binder { result = context.getConverter().convert(result, target); } if (result == null && create) { - result = create(target, context); + result = fromDataObjectBinders(target.getBindMethod(), + (dataObjectBinder) -> dataObjectBinder.create(target, context)); result = handler.onCreate(name, target, context, result); result = context.getConverter().convert(result, target); Assert.state(result != null, () -> "Unable to create instance for " + target.getType()); @@ -369,16 +372,6 @@ public class Binder { return context.getConverter().convert(result, target); } - private Object create(Bindable target, Context context) { - for (DataObjectBinder dataObjectBinder : this.dataObjectBinders.get(target.getBindMethod())) { - Object instance = dataObjectBinder.create(target, context); - if (instance != null) { - return instance; - } - } - return null; - } - private T handleBindError(ConfigurationPropertyName name, Bindable target, BindHandler handler, Context context, Exception error) { try { @@ -477,15 +470,17 @@ public class Binder { } DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName), propertyTarget, handler, context, false, false); - return context.withDataObject(type, () -> { - for (DataObjectBinder dataObjectBinder : this.dataObjectBinders.get(bindMethod)) { - Object instance = dataObjectBinder.bind(name, target, context, propertyBinder); - if (instance != null) { - return instance; - } - } - return null; - }); + return context.withDataObject(type, () -> fromDataObjectBinders(bindMethod, + (dataObjectBinder) -> dataObjectBinder.bind(name, target, context, propertyBinder))); + } + + private Object fromDataObjectBinders(BindMethod bindMethod, Function operation) { + return this.dataObjectBinders.get(bindMethod) + .stream() + .map(operation) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); } private boolean isUnbindableBean(ConfigurationPropertyName name, Bindable target, Context context) { diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/DataObjectBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/DataObjectBinder.java index 4bf63dd665..6fdd230c6d 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/DataObjectBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/DataObjectBinder.java @@ -33,11 +33,11 @@ interface DataObjectBinder { /** * Return a bound instance or {@code null} if the {@link DataObjectBinder} does not * support the specified {@link Bindable}. + * @param the source type * @param name the name being bound * @param target the bindable to bind * @param context the bind context * @param propertyBinder property binder - * @param the source type * @return a bound instance or {@code null} */ T bind(ConfigurationPropertyName name, Bindable target, Context context, @@ -46,9 +46,9 @@ interface DataObjectBinder { /** * Return a newly created instance or {@code null} if the {@link DataObjectBinder} * does not support the specified {@link Bindable}. + * @param the source type * @param target the bindable to create * @param context the bind context - * @param the source type * @return the created instance */ T create(Bindable target, Context context);