configurers) {
- this.configurers.addConfigurers(configurers);
+ this.configurers.addWebMvcConfigurers(configurers);
}
public void setServletContext(ServletContext servletContext) {
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
index 3ae69ce03fa..59e392fc5b6 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
@@ -54,7 +54,7 @@ public interface WebMvcConfigurer {
/**
* Add {@link Converter}s and {@link Formatter}s in addition to the ones registered by default.
*/
- void addFormatters(FormatterRegistry formatterRegistry);
+ void addFormatters(FormatterRegistry registry);
/**
* Configure the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
@@ -102,20 +102,20 @@ public interface WebMvcConfigurer {
* invocation. Interceptors can be registered to apply to all requests or limited to a set of path patterns.
* @see InterceptorConfigurer
*/
- void configureInterceptors(InterceptorConfigurer interceptorConfigurer);
+ void configureInterceptors(InterceptorConfigurer configurer);
/**
* Configure the view controllers to use. A view controller is used to map a URL path directly to a view name.
* This is convenient when a request does not require controller logic.
*/
- void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer);
+ void configureViewControllers(ViewControllerConfigurer configurer);
/**
* Configure a handler for serving static resources such as images, js, and, css files through Spring MVC
* including setting cache headers optimized for efficient loading in a web browser. Resources can be served
* out of locations under web application root, from the classpath, and others.
*/
- void configureResourceHandling(ResourceConfigurer resourceConfigurer);
+ void configureResourceHandling(ResourceConfigurer configurer);
/**
* Configure a handler for delegating unhandled requests by forwarding to the Servlet container's default
@@ -123,6 +123,6 @@ public interface WebMvcConfigurer {
* cleaner URLs (without a servlet prefix) but may need to still allow some requests (e.g. static resources)
* to be handled by the Servlet container's default servlet.
*/
- void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer);
+ void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
index 671fc54f3cd..d3ef44d8c51 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
@@ -38,7 +38,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
* {@inheritDoc}
* This implementation is empty.
*/
- public void addFormatters(FormatterRegistry formatterRegistry) {
+ public void addFormatters(FormatterRegistry registry) {
}
/**
@@ -81,28 +81,28 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureInterceptors(InterceptorConfigurer interceptorConfigurer) {
+ public void configureInterceptors(InterceptorConfigurer configurer) {
}
/**
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
+ public void configureViewControllers(ViewControllerConfigurer configurer) {
}
/**
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
+ public void configureResourceHandling(ResourceConfigurer configurer) {
}
/**
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}
}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
index efc09b3ae1e..5a602174275 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
@@ -36,74 +36,74 @@ import org.springframework.web.servlet.HandlerExceptionResolver;
*/
class WebMvcConfigurerComposite implements WebMvcConfigurer {
- private final List configurers = new ArrayList();
+ private final List delegates = new ArrayList();
- public void addConfigurers(List configurers) {
+ public void addWebMvcConfigurers(List configurers) {
if (configurers != null) {
- this.configurers.addAll(configurers);
+ this.delegates.addAll(configurers);
}
}
- public void addFormatters(FormatterRegistry formatterRegistry) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.addFormatters(formatterRegistry);
+ public void addFormatters(FormatterRegistry registry) {
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.addFormatters(registry);
}
}
public void configureMessageConverters(List> converters) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureMessageConverters(converters);
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureMessageConverters(converters);
}
}
public void addArgumentResolvers(List argumentResolvers) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.addArgumentResolvers(argumentResolvers);
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.addArgumentResolvers(argumentResolvers);
}
}
public void addReturnValueHandlers(List returnValueHandlers) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.addReturnValueHandlers(returnValueHandlers);
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.addReturnValueHandlers(returnValueHandlers);
}
}
public void configureHandlerExceptionResolvers(List exceptionResolvers) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureHandlerExceptionResolvers(exceptionResolvers);
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureHandlerExceptionResolvers(exceptionResolvers);
}
}
- public void configureInterceptors(InterceptorConfigurer interceptorRegistry) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureInterceptors(interceptorRegistry);
+ public void configureInterceptors(InterceptorConfigurer configurer) {
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureInterceptors(configurer);
}
}
- public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureViewControllers(viewControllerConfigurer);
+ public void configureViewControllers(ViewControllerConfigurer configurer) {
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureViewControllers(configurer);
}
}
- public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureResourceHandling(resourceConfigurer);
+ public void configureResourceHandling(ResourceConfigurer configurer) {
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureResourceHandling(configurer);
}
}
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
- for (WebMvcConfigurer configurer : configurers) {
- configurer.configureDefaultServletHandling(handlerConfigurer);
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ for (WebMvcConfigurer delegate : delegates) {
+ delegate.configureDefaultServletHandling(configurer);
}
}
public Validator getValidator() {
Map validators = new HashMap();
- for (WebMvcConfigurer configurer : configurers) {
- Validator validator = configurer.getValidator();
+ for (WebMvcConfigurer delegate : delegates) {
+ Validator validator = delegate.getValidator();
if (validator != null) {
- validators.put(configurer, validator);
+ validators.put(delegate, validator);
}
}
if (validators.size() == 0) {
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
index 502d43dce47..554fc456eaa 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMethodMapping.java
@@ -127,6 +127,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap
detectHandlerMethods(beanName);
}
}
+ handlerMethodsInitialized(getHandlerMethods());
}
/**
@@ -136,6 +137,13 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap
*/
protected abstract boolean isHandler(Class> beanType);
+ /**
+ * Invoked after all handler methods found in beans of the current ApplicationContext have been registered.
+ * @param handlerMethods a read-only map with mapping conditions (generic type {@code }) and HandlerMethods.
+ */
+ protected void handlerMethodsInitialized(Map handlerMethods) {
+ }
+
/**
* Detect and register handler methods for the specified handler.
* @param handler the bean name of a handler or a handler instance
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java
index e18777431d5..fe01e9887fd 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java
@@ -171,8 +171,10 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
/**
* Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and
- * {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values
- * ahead of the standard argument resolvers registered by default.
+ * {@link InitBinder} methods.
+ * Generally custom argument resolvers are invoked first. However this excludes
+ * default argument resolvers that rely on the presence of annotations (e.g. {@code @RequestParameter},
+ * {@code @PathVariable}, etc.) Those resolvers can only be customized via {@link #setArgumentResolvers(List)}
*
An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
*/
@@ -208,8 +210,9 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
/**
* Set custom return value handlers to use to handle the return values of {@link RequestMapping} methods.
- * Custom return value handlers are given a chance to handle a return value before the standard
- * return value handlers registered by default.
+ *
Generally custom return value handlers are invoked first. However this excludes default return value
+ * handlers that rely on the presence of annotations like {@code @ResponseBody}, {@code @ModelAttribute},
+ * and others. Those handlers can only be customized via {@link #setReturnValueHandlers(List)}.
* @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods
*/
public void setCustomReturnValueHandlers(List returnValueHandlers) {
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
index 9dfdf262e07..4f1810b408a 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java
@@ -17,6 +17,7 @@
package org.springframework.web.servlet.mvc.method.annotation;
import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
@@ -24,6 +25,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.annotation.AnnotationUtils;
@@ -93,6 +95,17 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping handlerMethods) {
+ List mappings = new ArrayList(handlerMethods.keySet());
+ while (mappings.size() > 1) {
+ RequestMappingInfo mapping = mappings.remove(0);
+ for (RequestMappingInfo otherMapping : mappings) {
+ // further validate mapping conditions
+ }
+ }
+ }
+
/**
* Provides a {@link RequestMappingInfo} for the given method.
* Only {@link RequestMapping @RequestMapping}-annotated methods are considered.