Skip to content

Commit

Permalink
Defensive check for cglib proxy in RequestMappingEndpoint
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dsyer committed Dec 10, 2014
1 parent e772174 commit de3ce18
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
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;
Expand Down Expand Up @@ -109,6 +110,10 @@ protected void extractHandlerMappings(ApplicationContext applicationContext,
.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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
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;
Expand Down Expand Up @@ -69,6 +75,18 @@ public void beanUrlMappings() {
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();
Expand Down Expand Up @@ -104,4 +122,15 @@ public void concreteMethodMappings() {
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;
}
}
}

0 comments on commit de3ce18

Please sign in to comment.