1
1
/*
2
- * Copyright 2002-2011 the original author or authors.
2
+ * Copyright 2002-2012 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
25
25
import java .util .List ;
26
26
import java .util .Map ;
27
27
import java .util .Set ;
28
-
29
28
import javax .servlet .ServletException ;
30
29
import javax .servlet .http .HttpServletRequest ;
31
30
32
31
import org .springframework .beans .factory .BeanFactoryUtils ;
33
- import org .springframework .context . ApplicationContextException ;
32
+ import org .springframework .beans . factory . InitializingBean ;
34
33
import org .springframework .util .ClassUtils ;
35
34
import org .springframework .util .LinkedMultiValueMap ;
36
35
import org .springframework .util .MultiValueMap ;
42
41
/**
43
42
* Abstract base class for {@link HandlerMapping} implementations that define a
44
43
* 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
- *
44
+ *
45
+ * <p>For each registered handler method, a unique mapping is maintained with
46
+ * subclasses defining the details of the mapping type {@code <T>}.
47
+ *
49
48
* @param <T> The mapping for a {@link HandlerMethod} containing the conditions
50
- * needed to match the handler method to incoming request.
51
- *
49
+ * needed to match the handler method to incoming request.
50
+ *
52
51
* @author Arjen Poutsma
53
52
* @author Rossen Stoyanchev
54
53
* @since 3.1
55
54
*/
56
- public abstract class AbstractHandlerMethodMapping <T > extends AbstractHandlerMapping {
55
+ public abstract class AbstractHandlerMethodMapping <T > extends AbstractHandlerMapping implements InitializingBean {
57
56
58
57
private boolean detectHandlerMethodsInAncestorContexts = false ;
59
58
60
59
private final Map <T , HandlerMethod > handlerMethods = new LinkedHashMap <T , HandlerMethod >();
61
60
62
61
private final MultiValueMap <String , T > urlMap = new LinkedMultiValueMap <String , T >();
63
62
63
+
64
64
/**
65
65
* Whether to detect handler methods in beans in ancestor ApplicationContexts.
66
66
* <p>Default is "false": Only beans in the current ApplicationContext are
@@ -72,20 +72,18 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
72
72
public void setDetectHandlerMethodsInAncestorContexts (boolean detectHandlerMethodsInAncestorContexts ) {
73
73
this .detectHandlerMethodsInAncestorContexts = detectHandlerMethodsInAncestorContexts ;
74
74
}
75
-
75
+
76
76
/**
77
77
* Return a map with all handler methods and their mappings.
78
78
*/
79
79
public Map <T , HandlerMethod > getHandlerMethods () {
80
- return Collections .unmodifiableMap (handlerMethods );
80
+ return Collections .unmodifiableMap (this . handlerMethods );
81
81
}
82
82
83
83
/**
84
- * ApplicationContext initialization and handler method detection .
84
+ * Detects handler methods at initialization .
85
85
*/
86
- @ Override
87
- public void initApplicationContext () throws ApplicationContextException {
88
- super .initApplicationContext ();
86
+ public void afterPropertiesSet () {
89
87
initHandlerMethods ();
90
88
}
91
89
@@ -99,7 +97,7 @@ protected void initHandlerMethods() {
99
97
if (logger .isDebugEnabled ()) {
100
98
logger .debug ("Looking for request mappings in application context: " + getApplicationContext ());
101
99
}
102
-
100
+
103
101
String [] beanNames = (this .detectHandlerMethodsInAncestorContexts ?
104
102
BeanFactoryUtils .beanNamesForTypeIncludingAncestors (getApplicationContext (), Object .class ) :
105
103
getApplicationContext ().getBeanNamesForType (Object .class ));
@@ -131,27 +129,26 @@ protected void handlerMethodsInitialized(Map<T, HandlerMethod> handlerMethods) {
131
129
* @param handler the bean name of a handler or a handler instance
132
130
*/
133
131
protected void detectHandlerMethods (final Object handler ) {
134
- Class <?> handlerType = (handler instanceof String ) ?
132
+ Class <?> handlerType = (handler instanceof String ) ?
135
133
getApplicationContext ().getType ((String ) handler ) : handler .getClass ();
136
134
137
135
final Class <?> userType = ClassUtils .getUserClass (handlerType );
138
-
136
+
139
137
Set <Method > methods = HandlerMethodSelector .selectMethods (userType , new MethodFilter () {
140
138
public boolean matches (Method method ) {
141
139
return getMappingForMethod (method , userType ) != null ;
142
140
}
143
141
});
144
-
142
+
145
143
for (Method method : methods ) {
146
144
T mapping = getMappingForMethod (method , userType );
147
145
registerHandlerMethod (handler , method , mapping );
148
146
}
149
147
}
150
148
151
149
/**
152
- * Provide the mapping for a handler method. A method for which no
150
+ * Provide the mapping for a handler method. A method for which no
153
151
* mapping can be provided is not a handler method.
154
- *
155
152
* @param method the method to provide a mapping for
156
153
* @param handlerType the handler type, possibly a sub-type of the method's
157
154
* declaring class
@@ -161,11 +158,10 @@ public boolean matches(Method method) {
161
158
162
159
/**
163
160
* Register a handler method and its unique mapping.
164
- *
165
161
* @param handler the bean name of the handler or the handler instance
166
162
* @param method the method to register
167
163
* @param mapping the mapping conditions associated with the handler method
168
- * @throws IllegalStateException if another method was already registered
164
+ * @throws IllegalStateException if another method was already registered
169
165
* under the same mapping
170
166
*/
171
167
protected void registerHandlerMethod (Object handler , Method method , T mapping ) {
@@ -177,29 +173,29 @@ protected void registerHandlerMethod(Object handler, Method method, T mapping) {
177
173
else {
178
174
handlerMethod = new HandlerMethod (handler , method );
179
175
}
180
-
176
+
181
177
HandlerMethod oldHandlerMethod = handlerMethods .get (mapping );
182
178
if (oldHandlerMethod != null && !oldHandlerMethod .equals (handlerMethod )) {
183
179
throw new IllegalStateException ("Ambiguous mapping found. Cannot map '" + handlerMethod .getBean ()
184
180
+ "' bean method \n " + handlerMethod + "\n to " + mapping + ": There is already '"
185
181
+ oldHandlerMethod .getBean () + "' bean method\n " + oldHandlerMethod + " mapped." );
186
182
}
187
-
188
- handlerMethods .put (mapping , handlerMethod );
183
+
184
+ this . handlerMethods .put (mapping , handlerMethod );
189
185
if (logger .isInfoEnabled ()) {
190
186
logger .info ("Mapped \" " + mapping + "\" onto " + handlerMethod );
191
187
}
192
-
188
+
193
189
Set <String > patterns = getMappingPathPatterns (mapping );
194
190
for (String pattern : patterns ) {
195
191
if (!getPathMatcher ().isPattern (pattern )) {
196
- urlMap .add (pattern , mapping );
192
+ this . urlMap .add (pattern , mapping );
197
193
}
198
194
}
199
195
}
200
196
201
197
/**
202
- * Extract and return the URL paths contained in a mapping.
198
+ * Extract and return the URL paths contained in a mapping.
203
199
*/
204
200
protected abstract Set <String > getMappingPathPatterns (T mapping );
205
201
@@ -230,11 +226,9 @@ protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Ex
230
226
/**
231
227
* Look up the best-matching handler method for the current request.
232
228
* If multiple matches are found, the best match is selected.
233
- *
234
229
* @param lookupPath mapping lookup path within the current servlet mapping
235
230
* @param request the current request
236
231
* @return the best-matching handler method, or {@code null} if no match
237
- *
238
232
* @see #handleMatch(Object, String, HttpServletRequest)
239
233
* @see #handleNoMatch(Set, String, HttpServletRequest)
240
234
*/
@@ -289,9 +283,8 @@ private void addMatchingMappings(Collection<T> mappings, List<Match> matches, Ht
289
283
}
290
284
291
285
/**
292
- * Check if a mapping matches the current request and return a (potentially
286
+ * Check if a mapping matches the current request and return a (potentially
293
287
* new) mapping with conditions relevant to the current request.
294
- *
295
288
* @param mapping the mapping to get a match for
296
289
* @param request the current HTTP servlet request
297
290
* @return the match, or {@code null} if the mapping doesn't match
@@ -308,7 +301,7 @@ private void addMatchingMappings(Collection<T> mappings, List<Match> matches, Ht
308
301
309
302
/**
310
303
* Invoked when a matching mapping is found.
311
- * @param mapping the matching mapping
304
+ * @param mapping the matching mapping
312
305
* @param lookupPath mapping lookup path within the current servlet mapping
313
306
* @param request the current request
314
307
*/
@@ -325,9 +318,11 @@ protected void handleMatch(T mapping, String lookupPath, HttpServletRequest requ
325
318
*/
326
319
protected HandlerMethod handleNoMatch (Set <T > mappings , String lookupPath , HttpServletRequest request )
327
320
throws Exception {
321
+
328
322
return null ;
329
323
}
330
324
325
+
331
326
/**
332
327
* A temporary container for a mapping matched to a request.
333
328
*/
@@ -344,10 +339,11 @@ private Match(T mapping, HandlerMethod handlerMethod) {
344
339
345
340
@ Override
346
341
public String toString () {
347
- return mapping .toString ();
342
+ return this . mapping .toString ();
348
343
}
349
344
}
350
345
346
+
351
347
private class MatchComparator implements Comparator <Match > {
352
348
353
349
private final Comparator <T > comparator ;
@@ -357,8 +353,8 @@ public MatchComparator(Comparator<T> comparator) {
357
353
}
358
354
359
355
public int compare (Match match1 , Match match2 ) {
360
- return comparator .compare (match1 .mapping , match2 .mapping );
356
+ return this . comparator .compare (match1 .mapping , match2 .mapping );
361
357
}
362
358
}
363
-
364
- }
359
+
360
+ }
0 commit comments