Detect controller methods via InitializingBean hook

Previously RequestMappingHandlerMapping detected @RequestMapping
methods through an initApplicationContext() hook. However, the
HandlerMapping may not have been fully set up with all its
dependencies at that point including settings like useSuffixPattern
and others.

This change moves the detection @RequestMapping methods to an
InitializingBean.afterPropertiesSet() hook.

Issue: SPR-9371
This commit is contained in:
Rossen Stoyanchev
2012-05-10 16:42:36 -04:00
parent f61f4a960e
commit d7efc0db80
5 changed files with 45 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2011 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContextException; import org.springframework.context.ApplicationContextException;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
@@ -53,7 +54,7 @@ import org.springframework.web.servlet.HandlerMapping;
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @since 3.1 * @since 3.1
*/ */
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping { public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
private boolean detectHandlerMethodsInAncestorContexts = false; private boolean detectHandlerMethodsInAncestorContexts = false;
@@ -81,11 +82,17 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
} }
/** /**
* ApplicationContext initialization and handler method detection. * ApplicationContext initialization.
*/ */
@Override @Override
public void initApplicationContext() throws ApplicationContextException { public void initApplicationContext() throws ApplicationContextException {
super.initApplicationContext(); super.initApplicationContext();
}
/**
* Detects handler methods at initialization.
*/
public void afterPropertiesSet() {
initHandlerMethods(); initHandlerMethods();
} }

View File

@@ -83,6 +83,7 @@ public class WebMvcConfigurationSupportTests {
assertEquals(0, handlerMapping.getOrder()); assertEquals(0, handlerMapping.getOrder());
handlerMapping.setApplicationContext(cxt); handlerMapping.setApplicationContext(cxt);
handlerMapping.afterPropertiesSet();
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
assertNotNull(chain.getInterceptors()); assertNotNull(chain.getInterceptors());
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[0].getClass()); assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[0].getClass());
@@ -204,6 +205,7 @@ public class WebMvcConfigurationSupportTests {
RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping(); RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping();
rmHandlerMapping.setApplicationContext(appCxt); rmHandlerMapping.setApplicationContext(appCxt);
rmHandlerMapping.afterPropertiesSet();
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
assertNotNull(chain.getInterceptors()); assertNotNull(chain.getInterceptors());
assertEquals(2, chain.getInterceptors().length); assertEquals(2, chain.getInterceptors().length);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2011 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -98,12 +98,14 @@ public class HandlerMethodMappingTests {
AbstractHandlerMethodMapping<String> mapping1 = new MyHandlerMethodMapping(); AbstractHandlerMethodMapping<String> mapping1 = new MyHandlerMethodMapping();
mapping1.setApplicationContext(new StaticApplicationContext(cxt)); mapping1.setApplicationContext(new StaticApplicationContext(cxt));
mapping1.afterPropertiesSet();
assertEquals(0, mapping1.getHandlerMethods().size()); assertEquals(0, mapping1.getHandlerMethods().size());
AbstractHandlerMethodMapping<String> mapping2 = new MyHandlerMethodMapping(); AbstractHandlerMethodMapping<String> mapping2 = new MyHandlerMethodMapping();
mapping2.setDetectHandlerMethodsInAncestorContexts(true); mapping2.setDetectHandlerMethodsInAncestorContexts(true);
mapping2.setApplicationContext(new StaticApplicationContext(cxt)); mapping2.setApplicationContext(new StaticApplicationContext(cxt));
mapping2.afterPropertiesSet();
assertEquals(2, mapping2.getHandlerMethods().size()); assertEquals(2, mapping2.getHandlerMethods().size());
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2011 the original author or authors. * Copyright 2002-2012 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -103,6 +103,7 @@ public class HandlerMethodAnnotationDetectionTests {
context.refresh(); context.refresh();
handlerMapping.setApplicationContext(context); handlerMapping.setApplicationContext(context);
handlerMapping.afterPropertiesSet();
handlerAdapter.afterPropertiesSet(); handlerAdapter.afterPropertiesSet();
exceptionResolver.afterPropertiesSet(); exceptionResolver.afterPropertiesSet();
} }

View File

@@ -16,6 +16,7 @@ Changes in version 3.2 M1
* add Jackson 2 HttpMessageConverter and View types * add Jackson 2 HttpMessageConverter and View types
* add pretty print option to Jackson HttpMessageConverter and View types * add pretty print option to Jackson HttpMessageConverter and View types
* fix issue with resolving Errors controller method argument * fix issue with resolving Errors controller method argument
* detect controller methods via InitializingBean in RequestMappingHandlerMapping
Changes in version 3.1.1 (2012-02-16) Changes in version 3.1.1 (2012-02-16)
------------------------------------- -------------------------------------