mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-08-29 03:06:45 +08:00
Optimize CacheKey handling for immutable sources
Update `SpringIterableConfigurationPropertySource` so that cache keys do not need to be checked if property sources are immutable. See gh-16717
This commit is contained in:
parent
071410c437
commit
44d832158a
@ -25,6 +25,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.boot.env.OriginTrackedMapPropertySource;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
@ -192,21 +193,37 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
|
||||
|
||||
private final Object key;
|
||||
|
||||
private CacheKey(Object key) {
|
||||
private final int size;
|
||||
|
||||
private final boolean unmodifiableKey;
|
||||
|
||||
private CacheKey(Object key, boolean unmodifiableKey) {
|
||||
this.key = key;
|
||||
this.size = calculateSize(key);
|
||||
this.unmodifiableKey = unmodifiableKey;
|
||||
}
|
||||
|
||||
public CacheKey copy() {
|
||||
return new CacheKey(copyKey(this.key));
|
||||
return new CacheKey(copyKey(this.key), this.unmodifiableKey);
|
||||
}
|
||||
|
||||
private Object copyKey(Object key) {
|
||||
if (this.unmodifiableKey) {
|
||||
return key;
|
||||
}
|
||||
if (key instanceof Set) {
|
||||
return new HashSet<Object>((Set<?>) key);
|
||||
}
|
||||
return ((String[]) key).clone();
|
||||
}
|
||||
|
||||
private int calculateSize(Object key) {
|
||||
if (key instanceof Set) {
|
||||
return ((Set<?>) key).size();
|
||||
}
|
||||
return ((String[]) key).length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
@ -215,7 +232,11 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(this.key, ((CacheKey) obj).key);
|
||||
CacheKey otherCacheKey = (CacheKey) obj;
|
||||
if (this.size != otherCacheKey.size) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(this.key, otherCacheKey.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,9 +246,10 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
|
||||
|
||||
public static CacheKey get(EnumerablePropertySource<?> source) {
|
||||
if (source instanceof MapPropertySource) {
|
||||
return new CacheKey(((MapPropertySource) source).getSource().keySet());
|
||||
return new CacheKey(((MapPropertySource) source).getSource().keySet(),
|
||||
source instanceof OriginTrackedMapPropertySource);
|
||||
}
|
||||
return new CacheKey(source.getPropertyNames());
|
||||
return new CacheKey(source.getPropertyNames(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.env.OriginTrackedMapPropertySource;
|
||||
import org.springframework.boot.origin.Origin;
|
||||
import org.springframework.boot.origin.OriginLookup;
|
||||
import org.springframework.core.env.EnumerablePropertySource;
|
||||
@ -160,7 +161,7 @@ public class SpringIterableConfigurationPropertySourceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertySourceKeyDataChangeInvalidatesCache() {
|
||||
public void simpleMapPropertySourceKeyDataChangeInvalidatesCache() {
|
||||
// gh-13344
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("key1", "value1");
|
||||
@ -184,6 +185,18 @@ public class SpringIterableConfigurationPropertySourceTests {
|
||||
source, DefaultPropertyMapper.INSTANCE);
|
||||
assertThat(adapter.stream().count()).isEqualTo(2);
|
||||
map.setThrowException(true);
|
||||
}
|
||||
|
||||
public void originTrackedMapPropertySourceKeyAdditionInvalidatesCache() {
|
||||
// gh-13344
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("key1", "value1");
|
||||
map.put("key2", "value2");
|
||||
EnumerablePropertySource<?> source = new OriginTrackedMapPropertySource("test",
|
||||
map);
|
||||
SpringIterableConfigurationPropertySource adapter = new SpringIterableConfigurationPropertySource(
|
||||
source, DefaultPropertyMapper.INSTANCE);
|
||||
assertThat(adapter.stream().count()).isEqualTo(2);
|
||||
map.put("key3", "value3");
|
||||
assertThat(adapter.stream().count()).isEqualTo(3);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user