前置知识
参考我的另一篇博客,(209条消息) Servlet和SpringMVC_fengwuJ的博客-CSDN博客,描述了Servlet与SpringMVC的关系,大致可以知道从前端请求,到后端接口的中间过程
反序列化流程
-
前篇文章中,走到 getMethodParameters--------获取Controller方法形参,并循环依次填充 此步操作时,循环体里会有
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
该代码用于转换参数,args[i] 对应的是controller方法中参数列表的值
-
找到resolver this.resolvers.resolveArgument方法中,会调用 this.getArgumentResolver(parameter) 方法来获取具体的resolver,代码如下:
supportsParameter方法不同的resolver有不同的实现,此处以RequestResponseBodyMethodProcessor为例:
public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestBody.class); } public boolean supportsReturnType(MethodParameter returnType) { return AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class); }
- 使用resolver进行参数解析
- 本案例是使用xml作为body参数,所以找到MessageConverter------>MappingJackson2XmlHttpMessageConverter
5. 最终调用 AbstractJackson2HttpMessageConverter ----> this.objectMapper.readValue(inputMessage.getBody(), javaType);进行参数转化
继续跟进:
ObjectMapper--->
public <T> T readValue(InputStream src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { this._assertNotNull("src", src); return this._readMapAndClose(this._jsonFactory.createParser(src), valueType); }
ObjectMapper---> _readMapAndClose(JsonParser p0, JavaType valueType)
本案例首先获取到的deser为BeanDeserializer,方法如下:
_beanProperties中有_hashArea数组存储有SettableBeanProperty实例,但如何初始化设置的暂时还未找到......
SettableBeanProperty 类中包含有_valueDeserializer,初始化信息也未找到
此处进行反序列化操作
反序列化操作,从传入JsonParser处初次开始,就是一个递归操作;从JsonParser的首个节点开始,基于javaType类型,找到Deserializer实例,解析,存储,不停递归重复,直到结束