diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java index 2f30d2a23ca..cb180b2d357 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java @@ -34,6 +34,7 @@ import org.springframework.boot.context.event.ApplicationPreparedEvent; import org.springframework.boot.context.event.ApplicationStartingEvent; import org.springframework.boot.context.properties.bind.Bindable; import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.context.properties.source.ConfigurationPropertyName; import org.springframework.boot.logging.LogFile; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggingInitializationContext; @@ -88,6 +89,12 @@ import org.springframework.util.StringUtils; */ public class LoggingApplicationListener implements GenericApplicationListener { + private static final ConfigurationPropertyName LOGGING_LEVEL = ConfigurationPropertyName + .of("logging.level"); + + private static final ConfigurationPropertyName LOGGING_GROUP = ConfigurationPropertyName + .of("logging.group"); + private static final Bindable> STRING_STRING_MAP = Bindable .mapOf(String.class, String.class); @@ -324,8 +331,8 @@ public class LoggingApplicationListener implements GenericApplicationListener { } Binder binder = Binder.get(environment); Map groups = getGroups(); - binder.bind("logging.group", STRING_STRINGS_MAP.withExistingValue(groups)); - Map levels = binder.bind("logging.level", STRING_STRING_MAP) + binder.bind(LOGGING_GROUP, STRING_STRINGS_MAP.withExistingValue(groups)); + Map levels = binder.bind(LOGGING_LEVEL, STRING_STRING_MAP) .orElseGet(Collections::emptyMap); levels.forEach((name, level) -> { String[] groupedNames = groups.get(name); 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 bee05706981..58ca94ebe6a 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 @@ -30,7 +30,6 @@ import java.util.Set; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Stream; -import java.util.stream.StreamSupport; import org.springframework.beans.PropertyEditorRegistry; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -254,7 +253,7 @@ public class Binder { private Object bindObject(ConfigurationPropertyName name, Bindable target, BindHandler handler, Context context, boolean allowRecursiveBinding) { ConfigurationProperty property = findProperty(name, context); - if (property == null && containsNoDescendantOf(context.streamSources(), name)) { + if (property == null && containsNoDescendantOf(context.getSources(), name)) { return null; } AggregateBinder aggregateBinder = getAggregateBinder(target, context); @@ -310,9 +309,13 @@ public class Binder { if (name.isEmpty()) { return null; } - return context.streamSources() - .map((source) -> source.getConfigurationProperty(name)) - .filter(Objects::nonNull).findFirst().orElse(null); + for (ConfigurationPropertySource source : context.getSources()) { + ConfigurationProperty property = source.getConfigurationProperty(name); + if (property != null) { + return property; + } + } + return null; } private Object bindProperty(Bindable target, Context context, @@ -326,7 +329,7 @@ public class Binder { private Object bindBean(ConfigurationPropertyName name, Bindable target, BindHandler handler, Context context, boolean allowRecursiveBinding) { - if (containsNoDescendantOf(context.streamSources(), name) + if (containsNoDescendantOf(context.getSources(), name) || isUnbindableBean(name, target, context)) { return null; } @@ -345,10 +348,11 @@ public class Binder { private boolean isUnbindableBean(ConfigurationPropertyName name, Bindable target, Context context) { - if (context.streamSources().anyMatch((s) -> s - .containsDescendantOf(name) == ConfigurationPropertyState.PRESENT)) { - // We know there are properties to bind so we can't bypass anything - return false; + for (ConfigurationPropertySource source : context.getSources()) { + if (source.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT) { + // We know there are properties to bind so we can't bypass anything + return false; + } } Class resolved = target.getType().resolve(Object.class); if (resolved.isPrimitive() || NON_BEAN_CLASSES.contains(resolved)) { @@ -357,10 +361,14 @@ public class Binder { return resolved.getName().startsWith("java."); } - private boolean containsNoDescendantOf(Stream sources, + private boolean containsNoDescendantOf(Iterable sources, ConfigurationPropertyName name) { - return sources.allMatch( - (s) -> s.containsDescendantOf(name) == ConfigurationPropertyState.ABSENT); + for (ConfigurationPropertySource source : sources) { + if (source.containsDescendantOf(name) != ConfigurationPropertyState.ABSENT) { + return false; + } + } + return true; } /** @@ -453,13 +461,6 @@ public class Binder { this.configurationProperty = null; } - public Stream streamSources() { - if (this.sourcePushCount > 0) { - return this.source.stream(); - } - return StreamSupport.stream(Binder.this.sources.spliterator(), false); - } - public PlaceholdersResolver getPlaceholdersResolver() { return Binder.this.placeholdersResolver; } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java index 89e54038e96..a50b56e78b4 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java @@ -29,6 +29,7 @@ import java.util.function.Supplier; import org.springframework.beans.BeanUtils; import org.springframework.boot.context.properties.bind.Binder.Context; import org.springframework.boot.context.properties.source.ConfigurationPropertyName; +import org.springframework.boot.context.properties.source.ConfigurationPropertySource; import org.springframework.boot.context.properties.source.ConfigurationPropertyState; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; @@ -44,8 +45,7 @@ class JavaBeanBinder implements BeanBinder { @Override public T bind(ConfigurationPropertyName name, Bindable target, Context context, BeanPropertyBinder propertyBinder) { - boolean hasKnownBindableProperties = context.streamSources().anyMatch(( - s) -> s.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT); + boolean hasKnownBindableProperties = hasKnownBindableProperties(name, context); Bean bean = Bean.get(target, hasKnownBindableProperties); if (bean == null) { return null; @@ -55,6 +55,16 @@ class JavaBeanBinder implements BeanBinder { return (bound ? beanSupplier.get() : null); } + private boolean hasKnownBindableProperties(ConfigurationPropertyName name, + Context context) { + for (ConfigurationPropertySource source : context.getSources()) { + if (source.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT) { + return true; + } + } + return false; + } + private boolean bind(BeanPropertyBinder propertyBinder, Bean bean, BeanSupplier beanSupplier) { boolean bound = false; diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java index 45a7b8edaa0..8c3f7a4acb2 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java @@ -57,8 +57,7 @@ class MapBinder extends AggregateBinder> { Map map = CollectionFactory.createMap((target.getValue() != null) ? Map.class : target.getType().resolve(Object.class), 0); Bindable resolvedTarget = resolveTarget(target); - boolean hasDescendants = getContext().streamSources().anyMatch((source) -> source - .containsDescendantOf(name) == ConfigurationPropertyState.PRESENT); + boolean hasDescendants = hasDescendants(name); for (ConfigurationPropertySource source : getContext().getSources()) { if (!ConfigurationPropertyName.EMPTY.equals(name)) { ConfigurationProperty property = source.getConfigurationProperty(name); @@ -73,6 +72,15 @@ class MapBinder extends AggregateBinder> { return map.isEmpty() ? null : map; } + private boolean hasDescendants(ConfigurationPropertyName name) { + for (ConfigurationPropertySource source : getContext().getSources()) { + if (source.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT) { + return true; + } + } + return false; + } + private Bindable resolveTarget(Bindable target) { Class type = target.getType().resolve(Object.class); if (Properties.class.isAssignableFrom(type)) {