一般来说,通过反射是很难获得参数名的,只能取到参数类型,因为在编译时,参数名有可能是会改变的,需要在编译时加入参数才不会改变。
使用注解是可以实现取类型名(或者叫注解名)的,但是要写注解,并不方便。
观察Spring mvc框架中的数据绑定,发现是可以直接把http请求中对应参数绑定到对应的参数名上的,他是怎么实现的呢?
在getMethodArgumentValues方法中,MethodParameter[] parameters = getMethodParameters();这一句取到方法的所有参数,MethodParameter类型中有方法名的属性,这个是什么类呢?
是spring核心中的一个类,org.springframework.core.MethodParameter,并不是通过反射实现的。
方法getMethodParameters()是在HandlerMethod的类中
publicMethodParameter[] getMethodParameters() {
return this.parameters;
}
this.parameters则是在构造方法中初始化的:
publicHandlerMethod(Object bean, Method method) {
Assert.notNull(bean, "Bean is required");
Assert.notNull(method, "Method is required");
this.bean =bean;
this.beanFactory = null;
this.method =method;
this.bridgedMethod =BridgeMethodResolver.findBridgedMethod(method);
this.parameters =initMethodParameters();
}
initMethodParameters()生成了参数列表。
privateMethodParameter[] initMethodParameters() {
int count = this.bridgedMethod.getParameterTypes().length;
MethodParameter[] result = newMethodParameter[count];
for (int i = 0; i < count; i++) {
result[i] = newHandlerMethodParameter(i);
}
returnresult;
}
HandlerMethodParameter(i)是HandlerMethod的内部类,继承自MethodParameter
构造方法调用:
public HandlerMethodParameter(intindex) {
super(HandlerMethod.this.bridgedMethod, index);
}
再调用MethodParameter类的构造方法:
public MethodParameter(Method method, int parameterIndex, intnestingLevel) {
Assert.notNull(method, "Method must not be null");
this.method =method;
this.parameterIndex =parameterIndex;
this.nestingLevel =nestingLevel;
this.constructor = null;
}