当前位置: 首页 > 面试题库 >

Springs @RequestParam批注的内部工作

郑功
2023-03-14
问题内容

在Spring中,如果我没记错的话,以下两个语句是相同的:

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

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


问题答案:

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

有关此类似问题及其答案的其他详细信息。

在3.0.5.RELEASE中,这些注释在HandlerMethodInvoker.resolveHandlerArguments中进行处理,并且似乎没有提供任何值,Spring会使用RequestParam.value()。这可以返回空字符串。

再往下,Spring使用HandlerMethodInvoker.resolveRequestParam,在其中,如果参数名称为空,则HandlerMethodINvoker.getRequiredParameterName使用MethodParameter 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 }

请注意,这里它尝试从中提取信息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 }

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



 类似资料:
  • 问题内容: 请帮助我了解newFixedThreadPool(或Cached)的内部流程 当我们编写以下语句时,ExecutorService e = Executors.newFixedThreadPool(3); e.execute(runaable1); e.execute(runaable2); e.execute(runaable3); e.execute(runaable4); e.e

  • 请帮助我理解newFixedThreadPool(或Cached)的内部流 当我们编写下面的语句时,ExecutorService e=executors.NewFixedThreadPool(3); e.execute(runaable1); e.execute(runaable2); e.execute(runaable3); e.execute(runaable4); e.execute(r

  • 问题内容: 我有这个控制器方法: 但是,当我向该端点发送发布请求时,得到以下信息 当我从注释中删除params参数时,我得到了一个更一般的错误,它将说它找不到第一个必需的参数(开始),而实际上它与参数end,hours和username一起发送。 如何在Spring MVC中获取方法中的参数? 我在这篇文章中读到了只能用于get方法的内容,但是如果我删除并坚持使用批注的params参数,它仍然无法

  • 我有一个xml布局,它有以下视图:滚动视图->Relationvelayout->Some views+Tablayout+ViewPager->RecylerView(在ViewPager的片段中)。ViewPager有一些固定的高度(保持它“wrap_content”根本不会显示它)。现在的问题是Recylerview永远不会滚动。我已经尝试了几个已经发布的解决方案,比如在“嵌套滚动视图”中包

  • 问题内容: 我有一种通过以下方式注释的方法: 所以我知道这个注释: 此方法处理对由URL / orders* 表示的资源发出的 GET HTTP请求。 * 此方法调用返回 List 的DAO对象。 其中 Account 代表系统上的用户,并具有代表该用户的某些字段,例如: 我的问题是: 批注 到底如何工作? 它位于返回的对象之前,因此我认为它引用了此List。课程文档指出,此注释可用于: 确保结果

  • 问题内容: 有人可以向我解释注释在Java内部如何工作吗? 我知道如何通过使用Java中的java.lang.annotation库来创建自定义注释。但是我仍然不知道它在内部如何工作,例如@Override注释。 如果有人可以详细解释,我将非常感谢。 问题答案: 注释类型之间的第一个主要区别是它们是在编译时使用,然后丢弃(如)还是放在已编译的类文件中并在运行时可用(如Spring的)。这由注释的@