Commit de3ce18a authored by Dave Syer's avatar Dave Syer

Defensive check for cglib proxy in RequestMappingEndpoint

Since AbstractHandlerMethodMapping.getHandlerMap() is final it can't
be cglibbed and a proxy will barf if you try and call that method.
The RequestMappingEndpoint can be protected simply by defensively
checking if the mapping is a proxy before trying to inspect it.
parent e7721740
...@@ -23,6 +23,7 @@ import java.util.LinkedHashMap; ...@@ -23,6 +23,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
...@@ -109,6 +110,10 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object> ...@@ -109,6 +110,10 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
.getBeansOfType(AbstractUrlHandlerMapping.class); .getBeansOfType(AbstractUrlHandlerMapping.class);
for (String name : mappings.keySet()) { for (String name : mappings.keySet()) {
AbstractUrlHandlerMapping mapping = mappings.get(name); AbstractUrlHandlerMapping mapping = mappings.get(name);
if (AopUtils.isCglibProxy(mapping)) {
// The getHandlerMap() method is final so it cannot be cglibbed
continue;
}
Map<String, Object> handlers = mapping.getHandlerMap(); Map<String, Object> handlers = mapping.getHandlerMap();
for (String key : handlers.keySet()) { for (String key : handlers.keySet()) {
result.put(key, Collections.singletonMap("bean", name)); result.put(key, Collections.singletonMap("bean", name));
......
...@@ -23,6 +23,12 @@ import java.util.Map; ...@@ -23,6 +23,12 @@ import java.util.Map;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; 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.context.support.StaticApplicationContext;
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
...@@ -69,6 +75,18 @@ public class RequestMappingEndpointTests { ...@@ -69,6 +75,18 @@ public class RequestMappingEndpointTests {
assertEquals("mapping", map.get("bean")); assertEquals("mapping", map.get("bean"));
} }
@Test
public void beanUrlMappingsProxy() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
MappingConfiguration.class);
this.endpoint.setApplicationContext(context);
Map<String, Object> result = this.endpoint.invoke();
assertEquals(1, result.size());
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) result.get("/foo");
assertEquals("scopedTarget.mapping", map.get("bean"));
}
@Test @Test
public void beanMethodMappings() { public void beanMethodMappings() {
StaticApplicationContext context = new StaticApplicationContext(); StaticApplicationContext context = new StaticApplicationContext();
...@@ -104,4 +122,15 @@ public class RequestMappingEndpointTests { ...@@ -104,4 +122,15 @@ public class RequestMappingEndpointTests {
assertTrue(handler.containsKey("method")); 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;
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment