分析一下controller层中一个方法给了这么多参数,到底是如何确定其对应的值得:
首先进入handle方法:
最终都是通过invokeHandlerMethod得到的:
似乎根据是否是异步,有不同的生成方式,本文就看一下getModelAndView的方法:
继续运行,这里的关键点是argumentResolvers,字面意思就是参数解析器,听起来就很重要。。。
层层深入之后,找到比较底层的调用,这个方法getMethodArgumentValues就是用来找参数的:
关于参数解析器
关于afterPropertiesSet调用:https://www.cnblogs.com/javazhiyin/p/10905294.html
参数解析器在第一个if中获得
解析器一览:
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList();
resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), false));
resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver());
resolvers.add(new PathVariableMapMethodArgumentResolver());
resolvers.add(new MatrixVariableMethodArgumentResolver());
resolvers.add(new MatrixVariableMapMethodArgumentResolver());
resolvers.add(new ServletModelAttributeMethodProcessor(false));
resolvers.add(new RequestResponseBodyMethodProcessor(this.getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestPartMethodArgumentResolver(this.getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RequestHeaderMethodArgumentResolver(this.getBeanFactory()));
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
resolvers.add(new ServletCookieValueMethodArgumentResolver(this.getBeanFactory()));
resolvers.add(new ExpressionValueMethodArgumentResolver(this.getBeanFactory()));
resolvers.add(new SessionAttributeMethodArgumentResolver());
resolvers.add(new RequestAttributeMethodArgumentResolver());
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
resolvers.add(new HttpEntityMethodProcessor(this.getMessageConverters(), this.requestResponseBodyAdvice));
resolvers.add(new RedirectAttributesMethodArgumentResolver());
resolvers.add(new ModelMethodProcessor());
resolvers.add(new MapMethodProcessor());
resolvers.add(new ErrorsMethodArgumentResolver());
resolvers.add(new SessionStatusMethodArgumentResolver());
resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
if (this.getCustomArgumentResolvers() != null) {
resolvers.addAll(this.getCustomArgumentResolvers());
}
resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), true));
resolvers.add(new ServletModelAttributeMethodProcessor(true));
return resolvers;
}
总结一下:
所有类型都会找到其对应解析器,然后用解析器获得参数:
map里面的数据直接放到modelandview中:
自定义类型调用了这个解析器,先去mav中找数据,再去request中找数据:
对于JDK1.8以上的版本,可以直接读取字节码中的变量名。然后将变量名作为key从request中获取value。
因此只要名字能对应,@RequestParam可以省略。
关于参数的绑定有一篇很详细的文章:https://www.cnblogs.com/guangshan/p/4660564.html
大致流程:https://www.cnblogs.com/w-y-c-m/p/8443892.html