简体   繁体   English

Springs的@RequestParam注释的内部工作

[英]Internal working of Springs's @RequestParam annotation

In Spring, the two following statements are, if I'm not mistaken, identical: 在Spring中,如果我没有弄错的话,以下两个陈述是相同的:

@RequestParam("type") String type
@RequestParam String type

How can spring know the variable name of 'type' (second version). spring如何知道'type'的变量名(第二版)。 I was under the impression that this information was removed from the class files unless compiled with the -g flag (include debug information). 我的印象是,除非使用-g标志(包括调试信息)进行编译,否则将从类文件中删除此信息。

The short version of this is that apparently the parameter names are being compiled in, if they weren't, you'd get an exception indicating that Spring MVC couldn't deduce the parameter name. 这个的简短版本显然是编译参数名称,如果不是,你会得到一个异常,表明Spring MVC无法推断出参数名称。 That is, parameter names aren't always stored in the bytecode, but it seems like if they are, Spring will find them, if not, you need to specify them when you add the @RequestParam annotation. 也就是说,参数名称并不总是存储在字节码中,但看起来如果它们是,Spring会找到它们,如果没有,你需要在添加@RequestParam注释时指定它们。

Other details are available on this similar question and it's answers . 其他详细信息可以在这个类似的问题和它的答案


In 3.0.5.RELEASE, these annotations are processed in HandlerMethodInvoker.resolveHandlerArguments and it appears that if no value is supplied, Spring uses RequestParam.value() . 在3.0.5.RELEASE中,这些注释在HandlerMethodInvoker.resolveHandlerArguments中处理,如果没有提供任何值,Spring似乎使用RequestParam.value() This can return the empty string. 这可以返回空字符串。

Further down, Spring uses HandlerMethodInvoker.resolveRequestParam , and inside there, if the parameter name is empty, it invokes HandlerMethodINvoker.getRequiredParameterName with MethodParameter methodParam as an argument: 再往下,Spring使用HandlerMethodInvoker.resolveRequestParam ,在那里,如果参数名称为空,则使用MethodParameter methodParam作为参数调用HandlerMethodINvoker.getRequiredParameterName

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 }

Note that here it tries to pull the information from methodParam , which, if we back up the tree, we see that resolveHandlerArguments actually creates a new MethodParameter for each argument that it processes. 请注意,这里尝试从methodParam提取信息,如果我们备份树,我们会看到resolveHandlerArguments实际为它处理的每个参数创建一个新的MethodParameter Inside MethodParameter , we can take a look at getParameterName() : 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 }

So this uses something called a ParameterNameDiscoverer , but this is an interface and my trace isn't showing which implementation it's using, there are a few . 所以这使用了一个名为ParameterNameDiscoverer东西,但这是一个接口,我的跟踪没有显示它正在使用哪个实现,有一些 Looking at LocalVariableTableParameterNameDiscoverer.getParameterNames we end up calling a LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor as part of an org.objectweb.asm.ClassReader , which as far as I can tell tries to read the parameter name out of the bytecode. 查看LocalVariableTableParameterNameDiscoverer.getParameterNames,我们最终调用LocalVariableTableParameterNameDiscoverer.ParameterNameDiscoveringVisitor作为org.objectweb.asm.ClassReader一部分,据我所知,尝试从字节码中读取参数名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM