Browse Source

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.
pull/2106/head
Dave Syer 11 years ago
parent
commit
de3ce18ad6
  1. 5
      spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java
  2. 29
      spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java

5
spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpoint.java

@ -23,6 +23,7 @@ import java.util.LinkedHashMap; @@ -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<Map<String, Object> @@ -109,6 +110,10 @@ public class RequestMappingEndpoint extends AbstractEndpoint<Map<String, Object>
.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<String, Object> handlers = mapping.getHandlerMap();
for (String key : handlers.keySet()) {
result.put(key, Collections.singletonMap("bean", name));

29
spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/RequestMappingEndpointTests.java

@ -23,6 +23,12 @@ import java.util.Map; @@ -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 { @@ -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<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
public void beanMethodMappings() {
StaticApplicationContext context = new StaticApplicationContext();
@ -104,4 +122,15 @@ public class RequestMappingEndpointTests { @@ -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;
}
}
}

Loading…
Cancel
Save