Reduce GC in SpringConfigurationPropertySource

Update `SpringConfigurationPropertySource` so that the
`DelegatingPropertyMapper` accepts a maximum of two values and does
not need to wrap arguments in an array. Also optimize the merge
operation to return a single result directly rather than always using
a new `List`.

Closes gh-14563
This commit is contained in:
Phillip Webb
2018-09-20 09:49:43 -07:00
parent 2bc3d8d01f
commit 0a187675b5

View File

@@ -16,9 +16,6 @@
package org.springframework.boot.context.properties.source;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
@@ -30,6 +27,7 @@ import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.env.SystemEnvironmentPropertySource;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* {@link ConfigurationPropertySource} backed by a non-enumerable Spring
@@ -217,34 +215,67 @@ class SpringConfigurationPropertySource implements ConfigurationPropertySource {
*/
private static class DelegatingPropertyMapper implements PropertyMapper {
private final PropertyMapper[] mappers;
private static final PropertyMapping[] NONE = {};
DelegatingPropertyMapper(PropertyMapper... mappers) {
this.mappers = mappers;
private final PropertyMapper first;
private final PropertyMapper second;
DelegatingPropertyMapper(PropertyMapper first) {
this(first, null);
}
DelegatingPropertyMapper(PropertyMapper first, PropertyMapper second) {
this.first = first;
this.second = second;
}
@Override
public PropertyMapping[] map(
ConfigurationPropertyName configurationPropertyName) {
return callMappers((mapper) -> mapper.map(configurationPropertyName));
PropertyMapping[] first = map(this.first, configurationPropertyName);
PropertyMapping[] second = map(this.second, configurationPropertyName);
return merge(first, second);
}
private PropertyMapping[] map(PropertyMapper mapper,
ConfigurationPropertyName configurationPropertyName) {
try {
return (mapper != null) ? mapper.map(configurationPropertyName) : NONE;
}
catch (Exception ex) {
return NONE;
}
}
@Override
public PropertyMapping[] map(String propertySourceName) {
return callMappers((mapper) -> mapper.map(propertySourceName));
PropertyMapping[] first = map(this.first, propertySourceName);
PropertyMapping[] second = map(this.second, propertySourceName);
return merge(first, second);
}
private PropertyMapping[] callMappers(
Function<PropertyMapper, PropertyMapping[]> function) {
List<PropertyMapping> mappings = new ArrayList<>();
for (PropertyMapper mapper : this.mappers) {
try {
mappings.addAll(Arrays.asList(function.apply(mapper)));
}
catch (Exception ex) {
}
private PropertyMapping[] map(PropertyMapper mapper, String propertySourceName) {
try {
return (mapper != null) ? mapper.map(propertySourceName) : NONE;
}
return mappings.toArray(new PropertyMapping[] {});
catch (Exception ex) {
return NONE;
}
}
private PropertyMapping[] merge(PropertyMapping[] first,
PropertyMapping[] second) {
if (ObjectUtils.isEmpty(second)) {
return first;
}
if (ObjectUtils.isEmpty(first)) {
return second;
}
PropertyMapping[] merged = new PropertyMapping[first.length + second.length];
System.arraycopy(first, 0, merged, 0, first.length);
System.arraycopy(second, 0, merged, first.length, second.length);
return merged;
}
}