Skip to content

Commit 4853e6a

Browse files
rahul404philwebb
authored andcommitted
Skip scoped targets when determining endpoints
Update `EndpointDiscoverer` to filter out scoped target beans when finding endpoints. Closes gh-15182
1 parent 0bc4567 commit 4853e6a

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscoverer.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.function.Supplier;
3030
import java.util.stream.Collectors;
3131

32+
import org.springframework.aop.scope.ScopedProxyUtils;
3233
import org.springframework.beans.BeanUtils;
3334
import org.springframework.beans.factory.BeanFactoryUtils;
3435
import org.springframework.boot.actuate.endpoint.EndpointFilter;
@@ -131,11 +132,14 @@ private Collection<EndpointBean> createEndpointBeans() {
131132
this.applicationContext, Endpoint.class);
132133
for (String beanName : beanNames) {
133134
EndpointBean endpointBean = createEndpointBean(beanName);
134-
EndpointBean previous = byId.putIfAbsent(endpointBean.getId(), endpointBean);
135-
Assert.state(previous == null,
136-
() -> "Found two endpoints with the id '" + endpointBean.getId()
137-
+ "': '" + endpointBean.getBeanName() + "' and '"
138-
+ previous.getBeanName() + "'");
135+
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
136+
EndpointBean previous = byId.putIfAbsent(endpointBean.getId(),
137+
endpointBean);
138+
Assert.state(previous == null,
139+
() -> "Found two endpoints with the id '" + endpointBean.getId()
140+
+ "': '" + endpointBean.getBeanName() + "' and '"
141+
+ previous.getBeanName() + "'");
142+
}
139143
}
140144
return byId.values();
141145
}

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/EndpointDiscovererTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper;
4747
import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvoker;
4848
import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationInvokerAdvisor;
49+
import org.springframework.boot.actuate.endpoint.jmx.EndpointMBean;
4950
import org.springframework.context.ApplicationContext;
5051
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
5152
import org.springframework.context.annotation.Bean;
@@ -148,6 +149,18 @@ public void getEndpointsWhenTwoEndpointsHaveTheSameIdShouldThrowException() {
148149
});
149150
}
150151

152+
@Test
153+
public void getEndpointsWhenEndpointsArePrefixedWithScopedTargetShouldRegisterOnlyOneEndpoint() {
154+
load(ScopedTargetEndpointConfiguration.class, (
155+
context) -> {
156+
Collection<TestExposableEndpoint> endpoints =
157+
new TestEndpointDiscoverer(context).getEndpoints();
158+
assertThat(endpoints).hasSize(1);
159+
assertThat(endpoints.iterator().next().getEndpointBean()).isSameAs(context
160+
.getBean(ScopedTargetEndpointConfiguration.class).testEndpoint());
161+
});
162+
}
163+
151164
@Test
152165
public void getEndpointsWhenTtlSetToZeroShouldNotCacheInvokeCalls() {
153166
load(TestEndpointConfiguration.class, (context) -> {
@@ -393,6 +406,21 @@ public TestEndpoint testEndpointOne() {
393406

394407
}
395408

409+
@Configuration
410+
static class ScopedTargetEndpointConfiguration {
411+
412+
@Bean
413+
public TestEndpoint testEndpoint() {
414+
return new TestEndpoint();
415+
}
416+
417+
@Bean(name = "scopedTarget.testEndpoint")
418+
public TestEndpoint scopedTargetTestEndpoint() {
419+
return new TestEndpoint();
420+
}
421+
422+
}
423+
396424
@Import({ TestEndpoint.class, SpecializedTestEndpoint.class,
397425
SpecializedExtension.class })
398426
static class SpecializedEndpointsConfiguration {

0 commit comments

Comments
 (0)