Browse Source

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
pull/14975/head
Phillip Webb 7 years ago
parent
commit
1a85e629d7
  1. 11
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/logging/LoggingApplicationListener.java
  2. 41
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java
  3. 14
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/JavaBeanBinder.java
  4. 12
      spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/MapBinder.java

11
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; @@ -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; @@ -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 { @@ -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);

41
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/Binder.java

@ -30,7 +30,6 @@ import java.util.Set; @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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;
}

14
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; @@ -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 { @@ -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 { @@ -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;

12
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<Object, Object>> { @@ -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>> { @@ -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)) {

Loading…
Cancel
Save