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 be8fd6d610..28fbe1efbc 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 @@ -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"); * you may not use this file except in compliance with the License. @@ -25,12 +25,11 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.context.ApplicationContextException; +import org.springframework.beans.factory.InitializingBean; import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -42,18 +41,18 @@ import org.springframework.web.servlet.HandlerMapping; /** * Abstract base class for {@link HandlerMapping} implementations that define a * mapping between a request and a {@link HandlerMethod}. - * - *

For each registered handler method, a unique mapping is maintained with - * subclasses defining the details of the mapping type {@code }. - * + * + *

For each registered handler method, a unique mapping is maintained with + * subclasses defining the details of the mapping type {@code }. + * * @param The mapping for a {@link HandlerMethod} containing the conditions - * needed to match the handler method to incoming request. - * + * needed to match the handler method to incoming request. + * * @author Arjen Poutsma * @author Rossen Stoyanchev * @since 3.1 */ -public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping { +public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping implements InitializingBean { private boolean detectHandlerMethodsInAncestorContexts = false; @@ -61,6 +60,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap private final MultiValueMap urlMap = new LinkedMultiValueMap(); + /** * Whether to detect handler methods in beans in ancestor ApplicationContexts. *

Default is "false": Only beans in the current ApplicationContext are @@ -72,20 +72,18 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap public void setDetectHandlerMethodsInAncestorContexts(boolean detectHandlerMethodsInAncestorContexts) { this.detectHandlerMethodsInAncestorContexts = detectHandlerMethodsInAncestorContexts; } - + /** * Return a map with all handler methods and their mappings. */ public Map getHandlerMethods() { - return Collections.unmodifiableMap(handlerMethods); + return Collections.unmodifiableMap(this.handlerMethods); } /** - * ApplicationContext initialization and handler method detection. + * Detects handler methods at initialization. */ - @Override - public void initApplicationContext() throws ApplicationContextException { - super.initApplicationContext(); + public void afterPropertiesSet() { initHandlerMethods(); } @@ -99,7 +97,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap if (logger.isDebugEnabled()) { logger.debug("Looking for request mappings in application context: " + getApplicationContext()); } - + String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); @@ -131,17 +129,17 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap * @param handler the bean name of a handler or a handler instance */ protected void detectHandlerMethods(final Object handler) { - Class handlerType = (handler instanceof String) ? + Class handlerType = (handler instanceof String) ? getApplicationContext().getType((String) handler) : handler.getClass(); final Class userType = ClassUtils.getUserClass(handlerType); - + Set methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() { public boolean matches(Method method) { return getMappingForMethod(method, userType) != null; } }); - + for (Method method : methods) { T mapping = getMappingForMethod(method, userType); registerHandlerMethod(handler, method, mapping); @@ -149,9 +147,8 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap } /** - * Provide the mapping for a handler method. A method for which no + * Provide the mapping for a handler method. A method for which no * mapping can be provided is not a handler method. - * * @param method the method to provide a mapping for * @param handlerType the handler type, possibly a sub-type of the method's * declaring class @@ -161,11 +158,10 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * Register a handler method and its unique mapping. - * * @param handler the bean name of the handler or the handler instance * @param method the method to register * @param mapping the mapping conditions associated with the handler method - * @throws IllegalStateException if another method was already registered + * @throws IllegalStateException if another method was already registered * under the same mapping */ protected void registerHandlerMethod(Object handler, Method method, T mapping) { @@ -177,29 +173,29 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap else { handlerMethod = new HandlerMethod(handler, method); } - + HandlerMethod oldHandlerMethod = handlerMethods.get(mapping); if (oldHandlerMethod != null && !oldHandlerMethod.equals(handlerMethod)) { throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + handlerMethod.getBean() + "' bean method \n" + handlerMethod + "\nto " + mapping + ": There is already '" + oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped."); } - - handlerMethods.put(mapping, handlerMethod); + + this.handlerMethods.put(mapping, handlerMethod); if (logger.isInfoEnabled()) { logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod); } - + Set patterns = getMappingPathPatterns(mapping); for (String pattern : patterns) { if (!getPathMatcher().isPattern(pattern)) { - urlMap.add(pattern, mapping); + this.urlMap.add(pattern, mapping); } } } /** - * Extract and return the URL paths contained in a mapping. + * Extract and return the URL paths contained in a mapping. */ protected abstract Set getMappingPathPatterns(T mapping); @@ -230,11 +226,9 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * Look up the best-matching handler method for the current request. * If multiple matches are found, the best match is selected. - * * @param lookupPath mapping lookup path within the current servlet mapping * @param request the current request * @return the best-matching handler method, or {@code null} if no match - * * @see #handleMatch(Object, String, HttpServletRequest) * @see #handleNoMatch(Set, String, HttpServletRequest) */ @@ -289,9 +283,8 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap } /** - * Check if a mapping matches the current request and return a (potentially + * Check if a mapping matches the current request and return a (potentially * new) mapping with conditions relevant to the current request. - * * @param mapping the mapping to get a match for * @param request the current HTTP servlet request * @return the match, or {@code null} if the mapping doesn't match @@ -308,7 +301,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap /** * Invoked when a matching mapping is found. - * @param mapping the matching mapping + * @param mapping the matching mapping * @param lookupPath mapping lookup path within the current servlet mapping * @param request the current request */ @@ -325,9 +318,11 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap */ protected HandlerMethod handleNoMatch(Set mappings, String lookupPath, HttpServletRequest request) throws Exception { + return null; } + /** * A temporary container for a mapping matched to a request. */ @@ -344,10 +339,11 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap @Override public String toString() { - return mapping.toString(); + return this.mapping.toString(); } } + private class MatchComparator implements Comparator { private final Comparator comparator; @@ -357,8 +353,8 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap } public int compare(Match match1, Match match2) { - return comparator.compare(match1.mapping, match2.mapping); + return this.comparator.compare(match1.mapping, match2.mapping); } } - -} \ No newline at end of file + +}