1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.web.method;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Method;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 import org.springframework.beans.factory.BeanFactory;
26 import org.springframework.core.BridgeMethodResolver;
27 import org.springframework.core.MethodParameter;
28 import org.springframework.core.annotation.AnnotationUtils;
29 import org.springframework.util.Assert;
30 import org.springframework.util.ClassUtils;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class HandlerMethod {
47
48
49 protected final Log logger = LogFactory.getLog(getClass());
50
51 private final Object bean;
52
53 private final BeanFactory beanFactory;
54
55 private final Class<?> beanType;
56
57 private final Method method;
58
59 private final Method bridgedMethod;
60
61 private final MethodParameter[] parameters;
62
63
64
65
66
67 public HandlerMethod(Object bean, Method method) {
68 Assert.notNull(bean, "Bean is required");
69 Assert.notNull(method, "Method is required");
70 this.bean = bean;
71 this.beanFactory = null;
72 this.beanType = ClassUtils.getUserClass(bean);
73 this.method = method;
74 this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
75 this.parameters = initMethodParameters();
76 }
77
78
79
80
81
82 public HandlerMethod(Object bean, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
83 Assert.notNull(bean, "Bean is required");
84 Assert.notNull(methodName, "Method name is required");
85 this.bean = bean;
86 this.beanFactory = null;
87 this.beanType = ClassUtils.getUserClass(bean);
88 this.method = bean.getClass().getMethod(methodName, parameterTypes);
89 this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method);
90 this.parameters = initMethodParameters();
91 }
92
93
94
95
96
97
98 public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) {
99 Assert.hasText(beanName, "Bean name is required");
100 Assert.notNull(beanFactory, "BeanFactory is required");
101 Assert.notNull(method, "Method is required");
102 this.bean = beanName;
103 this.beanFactory = beanFactory;
104 this.beanType = ClassUtils.getUserClass(beanFactory.getType(beanName));
105 this.method = method;
106 this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
107 this.parameters = initMethodParameters();
108 }
109
110
111
112
113 protected HandlerMethod(HandlerMethod handlerMethod) {
114 Assert.notNull(handlerMethod, "HandlerMethod is required");
115 this.bean = handlerMethod.bean;
116 this.beanFactory = handlerMethod.beanFactory;
117 this.beanType = handlerMethod.beanType;
118 this.method = handlerMethod.method;
119 this.bridgedMethod = handlerMethod.bridgedMethod;
120 this.parameters = handlerMethod.parameters;
121 }
122
123
124
125
126 private HandlerMethod(HandlerMethod handlerMethod, Object handler) {
127 Assert.notNull(handlerMethod, "HandlerMethod is required");
128 Assert.notNull(handler, "Handler object is required");
129 this.bean = handler;
130 this.beanFactory = handlerMethod.beanFactory;
131 this.beanType = handlerMethod.beanType;
132 this.method = handlerMethod.method;
133 this.bridgedMethod = handlerMethod.bridgedMethod;
134 this.parameters = handlerMethod.parameters;
135 }
136
137
138 private MethodParameter[] initMethodParameters() {
139 int count = this.bridgedMethod.getParameterTypes().length;
140 MethodParameter[] result = new MethodParameter[count];
141 for (int i = 0; i < count; i++) {
142 result[i] = new HandlerMethodParameter(i);
143 }
144 return result;
145 }
146
147
148
149
150 public Object getBean() {
151 return this.bean;
152 }
153
154
155
156
157 public Method getMethod() {
158 return this.method;
159 }
160
161
162
163
164
165
166 public Class<?> getBeanType() {
167 return this.beanType;
168 }
169
170
171
172
173
174 protected Method getBridgedMethod() {
175 return this.bridgedMethod;
176 }
177
178
179
180
181 public MethodParameter[] getMethodParameters() {
182 return this.parameters;
183 }
184
185
186
187
188 public MethodParameter getReturnType() {
189 return new HandlerMethodParameter(-1);
190 }
191
192
193
194
195 public MethodParameter getReturnValueType(Object returnValue) {
196 return new ReturnValueMethodParameter(returnValue);
197 }
198
199
200
201
202 public boolean isVoid() {
203 return Void.TYPE.equals(getReturnType().getParameterType());
204 }
205
206
207
208
209
210
211
212 public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) {
213 return AnnotationUtils.findAnnotation(this.method, annotationType);
214 }
215
216
217
218
219
220 public HandlerMethod createWithResolvedBean() {
221 Object handler = this.bean;
222 if (this.bean instanceof String) {
223 String beanName = (String) this.bean;
224 handler = this.beanFactory.getBean(beanName);
225 }
226 return new HandlerMethod(this, handler);
227 }
228
229
230 @Override
231 public boolean equals(Object other) {
232 if (this == other) {
233 return true;
234 }
235 if (!(other instanceof HandlerMethod)) {
236 return false;
237 }
238 HandlerMethod otherMethod = (HandlerMethod) other;
239 return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method));
240 }
241
242 @Override
243 public int hashCode() {
244 return (this.bean.hashCode() * 31 + this.method.hashCode());
245 }
246
247 @Override
248 public String toString() {
249 return this.method.toGenericString();
250 }
251
252
253
254
255
256 protected class HandlerMethodParameter extends MethodParameter {
257
258 public HandlerMethodParameter(int index) {
259 super(HandlerMethod.this.bridgedMethod, index);
260 }
261
262 @Override
263 public Class<?> getContainingClass() {
264 return HandlerMethod.this.getBeanType();
265 }
266
267 @Override
268 public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) {
269 return HandlerMethod.this.getMethodAnnotation(annotationType);
270 }
271 }
272
273
274
275
276
277 private class ReturnValueMethodParameter extends HandlerMethodParameter {
278
279 private final Object returnValue;
280
281 public ReturnValueMethodParameter(Object returnValue) {
282 super(-1);
283 this.returnValue = returnValue;
284 }
285
286 @Override
287 public Class<?> getParameterType() {
288 return (this.returnValue != null ? this.returnValue.getClass() : super.getParameterType());
289 }
290 }
291
292 }