Skip to content

Commit bfc703a

Browse files
committed
Merge branch '2.6.x' into 2.7.x
Closes gh-31879
2 parents 3a9525b + 1e886bd commit bfc703a

File tree

2 files changed

+38
-18
lines changed

2 files changed

+38
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 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.
@@ -18,10 +18,10 @@
1818

1919
import java.util.Collections;
2020
import java.util.Iterator;
21-
import java.util.LinkedHashMap;
2221
import java.util.Map;
2322
import java.util.Map.Entry;
2423
import java.util.function.Function;
24+
import java.util.stream.Collectors;
2525

2626
import org.springframework.util.Assert;
2727

@@ -31,34 +31,36 @@
3131
* @param <V> the value type
3232
* @param <C> the contributor type
3333
* @author Phillip Webb
34+
* @author Guirong Hu
3435
* @see CompositeHealthContributorMapAdapter
3536
* @see CompositeReactiveHealthContributorMapAdapter
3637
*/
3738
abstract class NamedContributorsMapAdapter<V, C> implements NamedContributors<C> {
3839

39-
private final Map<String, V> map;
40-
41-
private final Function<V, ? extends C> valueAdapter;
40+
private final Map<String, C> map;
4241

4342
NamedContributorsMapAdapter(Map<String, V> map, Function<V, ? extends C> valueAdapter) {
4443
Assert.notNull(map, "Map must not be null");
4544
Assert.notNull(valueAdapter, "ValueAdapter must not be null");
4645
map.keySet().forEach(this::validateKey);
47-
map.values().stream().map(valueAdapter)
48-
.forEach((value) -> Assert.notNull(value, "Map must not contain null values"));
49-
this.map = Collections.unmodifiableMap(new LinkedHashMap<>(map));
50-
this.valueAdapter = valueAdapter;
46+
this.map = Collections.unmodifiableMap(map.entrySet().stream()
47+
.collect(Collectors.toMap(Entry::getKey, (entry) -> adapt(entry.getValue(), valueAdapter))));
5148
}
5249

5350
private void validateKey(String value) {
5451
Assert.notNull(value, "Map must not contain null keys");
5552
Assert.isTrue(!value.contains("/"), "Map keys must not contain a '/'");
53+
}
5654

55+
private C adapt(V value, Function<V, ? extends C> valueAdapter) {
56+
C contributor = (value != null) ? valueAdapter.apply(value) : null;
57+
Assert.notNull(contributor, "Map must not contain null values");
58+
return contributor;
5759
}
5860

5961
@Override
6062
public Iterator<NamedContributor<C>> iterator() {
61-
Iterator<Entry<String, V>> iterator = this.map.entrySet().iterator();
63+
Iterator<Entry<String, C>> iterator = this.map.entrySet().iterator();
6264
return new Iterator<NamedContributor<C>>() {
6365

6466
@Override
@@ -68,20 +70,16 @@ public boolean hasNext() {
6870

6971
@Override
7072
public NamedContributor<C> next() {
71-
Entry<String, V> entry = iterator.next();
72-
return NamedContributor.of(entry.getKey(), adapt(entry.getValue()));
73+
Entry<String, C> entry = iterator.next();
74+
return NamedContributor.of(entry.getKey(), entry.getValue());
7375
}
7476

7577
};
7678
}
7779

7880
@Override
7981
public C getContributor(String name) {
80-
return adapt(this.map.get(name));
81-
}
82-
83-
private C adapt(V value) {
84-
return (value != null) ? this.valueAdapter.apply(value) : null;
82+
return this.map.get(name);
8583
}
8684

8785
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/NamedContributorsMapAdapterTests.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 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.
@@ -20,6 +20,7 @@
2020
import java.util.Iterator;
2121
import java.util.LinkedHashMap;
2222
import java.util.Map;
23+
import java.util.concurrent.atomic.AtomicInteger;
2324
import java.util.function.Function;
2425

2526
import org.junit.jupiter.api.Test;
@@ -31,6 +32,7 @@
3132
* Tests for {@link NamedContributorsMapAdapter}.
3233
*
3334
* @author Phillip Webb
35+
* @author Guirong Hu
3436
*/
3537
class NamedContributorsMapAdapterTests {
3638

@@ -92,6 +94,21 @@ void getContributorReturnsAdaptedEntry() {
9294
assertThat(adapter.getContributor("two")).isEqualTo("owt");
9395
}
9496

97+
@Test
98+
void getContributorCallsAdaptersOnlyOnce() {
99+
Map<String, String> map = new LinkedHashMap<>();
100+
map.put("one", "one");
101+
map.put("two", "two");
102+
int callCount = map.size();
103+
AtomicInteger counter = new AtomicInteger(0);
104+
TestNamedContributorsMapAdapter<String> adapter = new TestNamedContributorsMapAdapter<>(map,
105+
(name) -> count(name, counter));
106+
assertThat(adapter.getContributor("one")).isEqualTo("eno");
107+
assertThat(counter.get()).isEqualTo(callCount);
108+
assertThat(adapter.getContributor("two")).isEqualTo("owt");
109+
assertThat(counter.get()).isEqualTo(callCount);
110+
}
111+
95112
@Test
96113
void getContributorWhenNotInMapReturnsNull() {
97114
TestNamedContributorsMapAdapter<String> adapter = createAdapter();
@@ -106,6 +123,11 @@ private TestNamedContributorsMapAdapter<String> createAdapter() {
106123
return adapter;
107124
}
108125

126+
private String count(CharSequence charSequence, AtomicInteger counter) {
127+
counter.incrementAndGet();
128+
return reverse(charSequence);
129+
}
130+
109131
private String reverse(CharSequence charSequence) {
110132
return new StringBuilder(charSequence).reverse().toString();
111133
}

0 commit comments

Comments
 (0)