赞
踩
大家都没理解我问的问题,可能是我提问的技巧还不是很好,不过我已经找到答案了。
我想问的是假如在Controller里的方法参数没有@RequestParam注解的时候,Spring是如何通过反射调用这个方法的,因为java的反射是无法获取参数名字的,无法获取参数名字就以为着无法把前端传来的参数找到方法中正确的参数。
现在我找到答案了:
在Spring中的类DefaultParameterNameDiscoverer (2.0.2.RELEASE):
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
private static final boolean kotlinPresent =
ClassUtils.isPresent("kotlin.Unit", DefaultParameterNameDiscoverer.class.getClassLoader());
public DefaultParameterNameDiscoverer() {
if (kotlinPresent) {
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
}
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
addDiscoverer(new LocalVariableTableParameterNameDiscoverer());
}
}
这个类是设置查找参数名方法的类,这里有三种
1.KotlinReflectionParameterNameDiscoverer:
看代码是判定是否为Kotlin,如果是就用这种,对于Kotlin我也不熟就没有细看
2.StandardReflectionParameterNameDiscoverer:
这是用java原生自带的反射原理获取参数名字
private String[] getParameterNames(Parameter[] parameters) {
String[] parameterNames = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
if (!param.isNamePresent()) {
return null;
}
parameterNames[i] = param.getName();
}
return parameterNames;
}
3.LocalVariableTableParameterNameDiscoverer
这是spring通过asm读取class字节码来获取方法的参数名字,具体的解释可以查看资料
所以Spring实际上是通过反射或者字节码读取获取方法的参数的名字的。
另外我这个Spring的源码2.0.2.RELEASE,由于2.X.X以上的版本要求jdk环境是1.8以上。在2.X.X一下的版本DefaultParameterNameDiscoverer类会先判断环境是否是1.8以上,如果是,在会调用
StandardReflectionParameterNameDiscoverer这个原生反射查找参数名的类,因为这个方法要jdk1.8以后才支持。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。