11/*
2- * Copyright 2002-2011 the original author or authors.
2+ * Copyright 2002-2012 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3030import javax .servlet .http .HttpServletRequest ;
3131
3232import org .springframework .beans .factory .BeanFactoryUtils ;
33+ import org .springframework .beans .factory .InitializingBean ;
3334import org .springframework .context .ApplicationContextException ;
3435import org .springframework .util .ClassUtils ;
3536import org .springframework .util .LinkedMultiValueMap ;
4243/**
4344 * Abstract base class for {@link HandlerMapping} implementations that define a
4445 * mapping between a request and a {@link HandlerMethod}.
45- *
46- * <p>For each registered handler method, a unique mapping is maintained with
47- * subclasses defining the details of the mapping type {@code <T>}.
48- *
46+ *
47+ * <p>For each registered handler method, a unique mapping is maintained with
48+ * subclasses defining the details of the mapping type {@code <T>}.
49+ *
4950 * @param <T> The mapping for a {@link HandlerMethod} containing the conditions
50- * needed to match the handler method to incoming request.
51- *
51+ * needed to match the handler method to incoming request.
52+ *
5253 * @author Arjen Poutsma
5354 * @author Rossen Stoyanchev
5455 * @since 3.1
5556 */
56- public abstract class AbstractHandlerMethodMapping <T > extends AbstractHandlerMapping {
57+ public abstract class AbstractHandlerMethodMapping <T > extends AbstractHandlerMapping implements InitializingBean {
5758
5859 private boolean detectHandlerMethodsInAncestorContexts = false ;
5960
@@ -72,7 +73,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
7273 public void setDetectHandlerMethodsInAncestorContexts (boolean detectHandlerMethodsInAncestorContexts ) {
7374 this .detectHandlerMethodsInAncestorContexts = detectHandlerMethodsInAncestorContexts ;
7475 }
75-
76+
7677 /**
7778 * Return a map with all handler methods and their mappings.
7879 */
@@ -81,11 +82,17 @@ public Map<T, HandlerMethod> getHandlerMethods() {
8182 }
8283
8384 /**
84- * ApplicationContext initialization and handler method detection .
85+ * ApplicationContext initialization.
8586 */
8687 @ Override
8788 public void initApplicationContext () throws ApplicationContextException {
8889 super .initApplicationContext ();
90+ }
91+
92+ /**
93+ * Detects handler methods at initialization.
94+ */
95+ public void afterPropertiesSet () {
8996 initHandlerMethods ();
9097 }
9198
@@ -99,7 +106,7 @@ protected void initHandlerMethods() {
99106 if (logger .isDebugEnabled ()) {
100107 logger .debug ("Looking for request mappings in application context: " + getApplicationContext ());
101108 }
102-
109+
103110 String [] beanNames = (this .detectHandlerMethodsInAncestorContexts ?
104111 BeanFactoryUtils .beanNamesForTypeIncludingAncestors (getApplicationContext (), Object .class ) :
105112 getApplicationContext ().getBeanNamesForType (Object .class ));
@@ -131,25 +138,25 @@ protected void handlerMethodsInitialized(Map<T, HandlerMethod> handlerMethods) {
131138 * @param handler the bean name of a handler or a handler instance
132139 */
133140 protected void detectHandlerMethods (final Object handler ) {
134- Class <?> handlerType = (handler instanceof String ) ?
141+ Class <?> handlerType = (handler instanceof String ) ?
135142 getApplicationContext ().getType ((String ) handler ) : handler .getClass ();
136143
137144 final Class <?> userType = ClassUtils .getUserClass (handlerType );
138-
145+
139146 Set <Method > methods = HandlerMethodSelector .selectMethods (userType , new MethodFilter () {
140147 public boolean matches (Method method ) {
141148 return getMappingForMethod (method , userType ) != null ;
142149 }
143150 });
144-
151+
145152 for (Method method : methods ) {
146153 T mapping = getMappingForMethod (method , userType );
147154 registerHandlerMethod (handler , method , mapping );
148155 }
149156 }
150157
151158 /**
152- * Provide the mapping for a handler method. A method for which no
159+ * Provide the mapping for a handler method. A method for which no
153160 * mapping can be provided is not a handler method.
154161 *
155162 * @param method the method to provide a mapping for
@@ -161,11 +168,11 @@ public boolean matches(Method method) {
161168
162169 /**
163170 * Register a handler method and its unique mapping.
164- *
171+ *
165172 * @param handler the bean name of the handler or the handler instance
166173 * @param method the method to register
167174 * @param mapping the mapping conditions associated with the handler method
168- * @throws IllegalStateException if another method was already registered
175+ * @throws IllegalStateException if another method was already registered
169176 * under the same mapping
170177 */
171178 protected void registerHandlerMethod (Object handler , Method method , T mapping ) {
@@ -177,19 +184,19 @@ protected void registerHandlerMethod(Object handler, Method method, T mapping) {
177184 else {
178185 handlerMethod = new HandlerMethod (handler , method );
179186 }
180-
187+
181188 HandlerMethod oldHandlerMethod = handlerMethods .get (mapping );
182189 if (oldHandlerMethod != null && !oldHandlerMethod .equals (handlerMethod )) {
183190 throw new IllegalStateException ("Ambiguous mapping found. Cannot map '" + handlerMethod .getBean ()
184191 + "' bean method \n " + handlerMethod + "\n to " + mapping + ": There is already '"
185192 + oldHandlerMethod .getBean () + "' bean method\n " + oldHandlerMethod + " mapped." );
186193 }
187-
194+
188195 handlerMethods .put (mapping , handlerMethod );
189196 if (logger .isInfoEnabled ()) {
190197 logger .info ("Mapped \" " + mapping + "\" onto " + handlerMethod );
191198 }
192-
199+
193200 Set <String > patterns = getMappingPathPatterns (mapping );
194201 for (String pattern : patterns ) {
195202 if (!getPathMatcher ().isPattern (pattern )) {
@@ -199,7 +206,7 @@ protected void registerHandlerMethod(Object handler, Method method, T mapping) {
199206 }
200207
201208 /**
202- * Extract and return the URL paths contained in a mapping.
209+ * Extract and return the URL paths contained in a mapping.
203210 */
204211 protected abstract Set <String > getMappingPathPatterns (T mapping );
205212
@@ -230,11 +237,11 @@ protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Ex
230237 /**
231238 * Look up the best-matching handler method for the current request.
232239 * If multiple matches are found, the best match is selected.
233- *
240+ *
234241 * @param lookupPath mapping lookup path within the current servlet mapping
235242 * @param request the current request
236243 * @return the best-matching handler method, or {@code null} if no match
237- *
244+ *
238245 * @see #handleMatch(Object, String, HttpServletRequest)
239246 * @see #handleNoMatch(Set, String, HttpServletRequest)
240247 */
@@ -289,7 +296,7 @@ private void addMatchingMappings(Collection<T> mappings, List<Match> matches, Ht
289296 }
290297
291298 /**
292- * Check if a mapping matches the current request and return a (potentially
299+ * Check if a mapping matches the current request and return a (potentially
293300 * new) mapping with conditions relevant to the current request.
294301 *
295302 * @param mapping the mapping to get a match for
@@ -308,7 +315,7 @@ private void addMatchingMappings(Collection<T> mappings, List<Match> matches, Ht
308315
309316 /**
310317 * Invoked when a matching mapping is found.
311- * @param mapping the matching mapping
318+ * @param mapping the matching mapping
312319 * @param lookupPath mapping lookup path within the current servlet mapping
313320 * @param request the current request
314321 */
@@ -360,5 +367,5 @@ public int compare(Match match1, Match match2) {
360367 return comparator .compare (match1 .mapping , match2 .mapping );
361368 }
362369 }
363-
370+
364371}
0 commit comments