Skip to content

Commit 6431833

Browse files
committed
Polish SpringIterableConfigurationPropertySource
1 parent 730b049 commit 6431833

File tree

1 file changed

+48
-46
lines changed

1 file changed

+48
-46
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/source/SpringIterableConfigurationPropertySource.java

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -55,7 +55,7 @@ class SpringIterableConfigurationPropertySource extends SpringConfigurationPrope
5555

5656
private final BiPredicate<ConfigurationPropertyName, ConfigurationPropertyName> ancestorOfCheck;
5757

58-
private final SoftReferenceConfigurationPropertyCache<Mappings> cache;
58+
private final SoftReferenceConfigurationPropertyCache<Cache> cache;
5959

6060
private volatile ConfigurationPropertyName[] configurationPropertyNames;
6161

@@ -101,7 +101,7 @@ public ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName
101101
if (configurationProperty != null) {
102102
return configurationProperty;
103103
}
104-
for (String candidate : getMappings().getMapped(name)) {
104+
for (String candidate : getCache().getMapped(name)) {
105105
Object value = getPropertySource().getProperty(candidate);
106106
if (value != null) {
107107
Origin origin = PropertySourceOrigin.get(getPropertySource(), candidate);
@@ -129,7 +129,7 @@ public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName
129129
return result;
130130
}
131131
if (this.ancestorOfCheck == PropertyMapper.DEFAULT_ANCESTOR_OF_CHECK) {
132-
return getMappings().containsDescendantOf(name, this.ancestorOfCheck);
132+
return getCache().containsDescendantOf(name, this.ancestorOfCheck);
133133
}
134134
ConfigurationPropertyName[] candidates = getConfigurationPropertyNames();
135135
for (ConfigurationPropertyName candidate : candidates) {
@@ -142,29 +142,29 @@ public ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName
142142

143143
private ConfigurationPropertyName[] getConfigurationPropertyNames() {
144144
if (!isImmutablePropertySource()) {
145-
return getMappings().getConfigurationPropertyNames(getPropertySource().getPropertyNames());
145+
return getCache().getConfigurationPropertyNames(getPropertySource().getPropertyNames());
146146
}
147147
ConfigurationPropertyName[] configurationPropertyNames = this.configurationPropertyNames;
148148
if (configurationPropertyNames == null) {
149-
configurationPropertyNames = getMappings()
149+
configurationPropertyNames = getCache()
150150
.getConfigurationPropertyNames(getPropertySource().getPropertyNames());
151151
this.configurationPropertyNames = configurationPropertyNames;
152152
}
153153
return configurationPropertyNames;
154154
}
155155

156-
private Mappings getMappings() {
157-
return this.cache.get(this::createMappings, this::updateMappings);
156+
private Cache getCache() {
157+
return this.cache.get(this::createCache, this::updateCache);
158158
}
159159

160-
private Mappings createMappings() {
161-
return new Mappings(getMappers(), isImmutablePropertySource(),
160+
private Cache createCache() {
161+
return new Cache(getMappers(), isImmutablePropertySource(),
162162
this.ancestorOfCheck == PropertyMapper.DEFAULT_ANCESTOR_OF_CHECK);
163163
}
164164

165-
private Mappings updateMappings(Mappings mappings) {
166-
mappings.updateMappings(getPropertySource()::getPropertyNames);
167-
return mappings;
165+
private Cache updateCache(Cache cache) {
166+
cache.update(getPropertySource()::getPropertyNames);
167+
return cache;
168168
}
169169

170170
private boolean isImmutablePropertySource() {
@@ -183,38 +183,30 @@ protected EnumerablePropertySource<?> getPropertySource() {
183183
return (EnumerablePropertySource<?>) super.getPropertySource();
184184
}
185185

186-
private static class Mappings {
186+
private static class Cache {
187187

188188
private static final ConfigurationPropertyName[] EMPTY_NAMES_ARRAY = {};
189189

190190
private final PropertyMapper[] mappers;
191191

192192
private final boolean immutable;
193193

194-
private final boolean trackDescendants;
194+
private final boolean captureDescendants;
195195

196-
private volatile Map<ConfigurationPropertyName, Set<String>> mappings;
196+
private volatile Data data;
197197

198-
private volatile Map<String, ConfigurationPropertyName> reverseMappings;
199-
200-
private volatile Map<ConfigurationPropertyName, Set<ConfigurationPropertyName>> descendants;
201-
202-
private volatile ConfigurationPropertyName[] configurationPropertyNames;
203-
204-
private volatile String[] lastUpdated;
205-
206-
Mappings(PropertyMapper[] mappers, boolean immutable, boolean trackDescendants) {
198+
Cache(PropertyMapper[] mappers, boolean immutable, boolean captureDescendants) {
207199
this.mappers = mappers;
208200
this.immutable = immutable;
209-
this.trackDescendants = trackDescendants;
201+
this.captureDescendants = captureDescendants;
210202
}
211203

212-
void updateMappings(Supplier<String[]> propertyNames) {
213-
if (this.mappings == null || !this.immutable) {
204+
void update(Supplier<String[]> propertyNames) {
205+
if (this.data == null || !this.immutable) {
214206
int count = 0;
215207
while (true) {
216208
try {
217-
updateMappings(propertyNames.get());
209+
tryUpdate(propertyNames.get());
218210
return;
219211
}
220212
catch (ConcurrentModificationException ex) {
@@ -226,36 +218,37 @@ void updateMappings(Supplier<String[]> propertyNames) {
226218
}
227219
}
228220

229-
private void updateMappings(String[] propertyNames) {
230-
String[] lastUpdated = this.lastUpdated;
221+
private void tryUpdate(String[] propertyNames) {
222+
Data data = this.data;
223+
String[] lastUpdated = (data != null) ? data.lastUpdated() : null;
231224
if (lastUpdated != null && Arrays.equals(lastUpdated, propertyNames)) {
232225
return;
233226
}
234227
int size = propertyNames.length;
235-
Map<ConfigurationPropertyName, Set<String>> mappings = cloneOrCreate(this.mappings, size);
236-
Map<String, ConfigurationPropertyName> reverseMappings = cloneOrCreate(this.reverseMappings, size);
237-
Map<ConfigurationPropertyName, Set<ConfigurationPropertyName>> descendants = cloneOrCreate(this.descendants,
238-
size);
228+
Map<ConfigurationPropertyName, Set<String>> mappings = cloneOrCreate(
229+
(data != null) ? data.mappings() : null, size);
230+
Map<String, ConfigurationPropertyName> reverseMappings = cloneOrCreate(
231+
(data != null) ? data.reverseMappings() : null, size);
232+
Map<ConfigurationPropertyName, Set<ConfigurationPropertyName>> descendants = cloneOrCreate(
233+
(data != null) ? data.descendants() : null, size);
239234
for (PropertyMapper propertyMapper : this.mappers) {
240235
for (String propertyName : propertyNames) {
241236
if (!reverseMappings.containsKey(propertyName)) {
242237
ConfigurationPropertyName configurationPropertyName = propertyMapper.map(propertyName);
243238
if (configurationPropertyName != null && !configurationPropertyName.isEmpty()) {
244239
add(mappings, configurationPropertyName, propertyName);
245240
reverseMappings.put(propertyName, configurationPropertyName);
246-
if (this.trackDescendants) {
241+
if (this.captureDescendants) {
247242
addParents(descendants, configurationPropertyName);
248243
}
249244
}
250245
}
251246
}
252247
}
253-
this.mappings = mappings;
254-
this.reverseMappings = reverseMappings;
255-
this.descendants = descendants;
256-
this.lastUpdated = this.immutable ? null : propertyNames;
257-
this.configurationPropertyNames = this.immutable
248+
ConfigurationPropertyName[] configurationPropertyNames = this.immutable
258249
? reverseMappings.values().toArray(new ConfigurationPropertyName[0]) : null;
250+
lastUpdated = this.immutable ? null : propertyNames;
251+
this.data = new Data(mappings, reverseMappings, descendants, configurationPropertyNames, lastUpdated);
259252
}
260253

261254
private <K, V> Map<K, V> cloneOrCreate(Map<K, V> source, int size) {
@@ -276,15 +269,16 @@ private <K, T> void add(Map<K, Set<T>> map, K key, T value) {
276269
}
277270

278271
Set<String> getMapped(ConfigurationPropertyName configurationPropertyName) {
279-
return this.mappings.getOrDefault(configurationPropertyName, Collections.emptySet());
272+
return this.data.mappings().getOrDefault(configurationPropertyName, Collections.emptySet());
280273
}
281274

282275
ConfigurationPropertyName[] getConfigurationPropertyNames(String[] propertyNames) {
283-
ConfigurationPropertyName[] names = this.configurationPropertyNames;
276+
Data data = this.data;
277+
ConfigurationPropertyName[] names = data.configurationPropertyNames();
284278
if (names != null) {
285279
return names;
286280
}
287-
Map<String, ConfigurationPropertyName> reverseMappings = this.reverseMappings;
281+
Map<String, ConfigurationPropertyName> reverseMappings = data.reverseMappings();
288282
if (reverseMappings == null || reverseMappings.isEmpty()) {
289283
return EMPTY_NAMES_ARRAY;
290284
}
@@ -297,10 +291,11 @@ ConfigurationPropertyName[] getConfigurationPropertyNames(String[] propertyNames
297291

298292
ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName name,
299293
BiPredicate<ConfigurationPropertyName, ConfigurationPropertyName> ancestorOfCheck) {
300-
if (name.isEmpty() && !this.descendants.isEmpty()) {
294+
Data data = this.data;
295+
if (name.isEmpty() && !data.descendants().isEmpty()) {
301296
return ConfigurationPropertyState.PRESENT;
302297
}
303-
Set<ConfigurationPropertyName> candidates = this.descendants.getOrDefault(name, Collections.emptySet());
298+
Set<ConfigurationPropertyName> candidates = data.descendants().getOrDefault(name, Collections.emptySet());
304299
for (ConfigurationPropertyName candidate : candidates) {
305300
if (ancestorOfCheck.test(name, candidate)) {
306301
return ConfigurationPropertyState.PRESENT;
@@ -309,6 +304,13 @@ ConfigurationPropertyState containsDescendantOf(ConfigurationPropertyName name,
309304
return ConfigurationPropertyState.ABSENT;
310305
}
311306

307+
private record Data(Map<ConfigurationPropertyName, Set<String>> mappings,
308+
Map<String, ConfigurationPropertyName> reverseMappings,
309+
Map<ConfigurationPropertyName, Set<ConfigurationPropertyName>> descendants,
310+
ConfigurationPropertyName[] configurationPropertyNames, String[] lastUpdated) {
311+
312+
}
313+
312314
}
313315

314316
/**

0 commit comments

Comments
 (0)