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.
This commit is contained in:
@@ -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>
|
|||||||
.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;
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user