Springs的@RequestParam注释的内部工作

Tob*_*ias 6 java spring annotations internal

在Spring中,如果我没有弄错的话,以下两个陈述是相同的:

@RequestParam("type") String type
@RequestParam String type
Run Code Online (Sandbox Code Playgroud)

spring如何知道'type'的变量名(第二版).我的印象是,除非使用-g标志(包括调试信息)进行编译,否则将从类文件中删除此信息.

Mar*_*iot 6

这个的简短版本显然是编译参数名称,如果不是,你会得到一个异常,表明Spring MVC无法推断出参数名称.也就是说,参数名称并不总是存储在字节码中,但看起来如果它们是,Spring会找到它们,如果没有,你需要在添加@RequestParam注释时指定它们.

其他详细信息可以在这个类似的问题和它的答案.


在3.0.5.RELEASE中,这些注释在HandlerMethodInvoker.resolveHandlerArguments中处理,看起来如果没有提供任何值,Spring会使用RequestParam.value().这可以返回空字符串.

再往下,Spring使用HandlerMethodInvoker.resolveRequestParam,里边有,如果参数名称是空的,它调用HandlerMethodINvoker.getRequiredParameterNameMethodParameter methodParam作为参数:

718     private String getRequiredParameterName(MethodParameter methodParam) {
719     String name = methodParam.getParameterName();
720     if (name == null) {
721         throw new IllegalStateException(
722                 "No parameter name specified for argument of type [" + methodParam.getParameterType().getName() +
723                         "], and no parameter name information found in class file either.");
724     }
725     return name;
726 }
Run Code Online (Sandbox Code Playgroud)

请注意,这里它试图从中提取信息methodParam,如果我们备份树,我们会看到它resolveHandlerArguments实际上MethodParameter为它处理的每个参数创建了一个新的信息.在里面MethodParameter,我们可以看看getParameterName():

276 public String getParameterName() {
277     if (this.parameterNameDiscoverer != null) {
278         String[] parameterNames = (this.method != null ?
279                 this.parameterNameDiscoverer.getParameterNames(this.method) :
280                 this.parameterNameDiscoverer.getParameterNames(this.constructor));
281         if (parameterNames != null) {
282             this.parameterName = parameterNames[this.parameterIndex];
283         }
284         this.parameterNameDiscoverer = null;
285     }
286     return this.parameterName;
287 }
Run Code Online (Sandbox Code Playgroud)

所以这使用了一个名为a的东西ParameterNameDiscoverer,但这是一个接口,我的跟踪没有显示它正在使用哪个实现,有一些.查看LocalVariableTableParameterNameDiscoverer.getParameterNames,我们最终调用a LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor作为一部分,org.objectweb.asm.ClassReader据我所知,尝试从字节码中读取参数名称.

  • 偏离主题,但是(LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor)确实是类名的标本. (2认同)