diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java index 87de684ff00..5c2a86e2e9a 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java @@ -23,6 +23,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -109,6 +110,10 @@ public class RequestMappingEndpoint extends AbstractEndpoint .getBeansOfType(AbstractUrlHandlerMapping.class); for (String name : mappings.keySet()) { AbstractUrlHandlerMapping mapping = mappings.get(name); + if (AopUtils.isCglibProxy(mapping)) { + // The getHandlerMap() method is final so it cannot be cglibbed + continue; + } Map handlers = mapping.getHandlerMap(); for (String key : handlers.keySet()) { result.put(key, Collections.singletonMap("bean", name)); diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java index 3e0de15719f..56fcc908900 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java @@ -23,6 +23,12 @@ import java.util.Map; import org.junit.Test; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.context.support.StaticApplicationContext; import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; @@ -69,6 +75,18 @@ public class RequestMappingEndpointTests { assertEquals("mapping", map.get("bean")); } + @Test + public void beanUrlMappingsProxy() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + MappingConfiguration.class); + this.endpoint.setApplicationContext(context); + Map result = this.endpoint.invoke(); + assertEquals(1, result.size()); + @SuppressWarnings("unchecked") + Map map = (Map) result.get("/foo"); + assertEquals("scopedTarget.mapping", map.get("bean")); + } + @Test public void beanMethodMappings() { StaticApplicationContext context = new StaticApplicationContext(); @@ -104,4 +122,15 @@ public class RequestMappingEndpointTests { assertTrue(handler.containsKey("method")); } + @Configuration + protected static class MappingConfiguration { + @Bean + @Lazy + @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) + public AbstractUrlHandlerMapping mapping() { + SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); + mapping.setUrlMap(Collections.singletonMap("/foo", new Object())); + return mapping; + } + } }