Stop using streams when working with sources
Replace `streamSources()` calls with `getSources()` in an attempt to reduce the amount of garbage created. Closes gh-13565
This commit is contained in:
@@ -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<Map<String, String>> STRING_STRING_MAP = Bindable
|
||||
.mapOf(String.class, String.class);
|
||||
|
||||
@@ -324,8 +331,8 @@ public class LoggingApplicationListener implements GenericApplicationListener {
|
||||
}
|
||||
Binder binder = Binder.get(environment);
|
||||
Map<String, String[]> groups = getGroups();
|
||||
binder.bind("logging.group", STRING_STRINGS_MAP.withExistingValue(groups));
|
||||
Map<String, String> levels = binder.bind("logging.level", STRING_STRING_MAP)
|
||||
binder.bind(LOGGING_GROUP, STRING_STRINGS_MAP.withExistingValue(groups));
|
||||
Map<String, String> levels = binder.bind(LOGGING_LEVEL, STRING_STRING_MAP)
|
||||
.orElseGet(Collections::emptyMap);
|
||||
levels.forEach((name, level) -> {
|
||||
String[] groupedNames = groups.get(name);
|
||||
|
||||
@@ -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 <T> Object bindObject(ConfigurationPropertyName name, Bindable<T> 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 <T> Object bindProperty(Bindable<T> 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<ConfigurationPropertySource> sources,
|
||||
private boolean containsNoDescendantOf(Iterable<ConfigurationPropertySource> 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<ConfigurationPropertySource> streamSources() {
|
||||
if (this.sourcePushCount > 0) {
|
||||
return this.source.stream();
|
||||
}
|
||||
return StreamSupport.stream(Binder.this.sources.spliterator(), false);
|
||||
}
|
||||
|
||||
public PlaceholdersResolver getPlaceholdersResolver() {
|
||||
return Binder.this.placeholdersResolver;
|
||||
}
|
||||
|
||||
@@ -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> T bind(ConfigurationPropertyName name, Bindable<T> target, Context context,
|
||||
BeanPropertyBinder propertyBinder) {
|
||||
boolean hasKnownBindableProperties = context.streamSources().anyMatch((
|
||||
s) -> s.containsDescendantOf(name) == ConfigurationPropertyState.PRESENT);
|
||||
boolean hasKnownBindableProperties = hasKnownBindableProperties(name, context);
|
||||
Bean<T> 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 <T> boolean bind(BeanPropertyBinder propertyBinder, Bean<T> bean,
|
||||
BeanSupplier<T> beanSupplier) {
|
||||
boolean bound = false;
|
||||
|
||||
@@ -57,8 +57,7 @@ class MapBinder extends AggregateBinder<Map<Object, Object>> {
|
||||
Map<Object, Object> 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<Map<Object, Object>> {
|
||||
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)) {
|
||||
|
||||
Reference in New Issue
Block a user