【springMVC源码分析】HandlerMethodReturnValueHandler返回值处理器

 HandlerMethodReturnValueHandler是一个Handler返回值的处理接口

它的实现类如下:

  

我们常用的是RequestResponseBodyMethodProcessor实现类它用来处理注解@RequestBody的方法(当然了@RestController也算)

RequestResponseBodyMethodProcessor既能处理@RequestBody返回值,也能处理@RequestBody参数注入。

 

HandlerMethod类

是对Handler方法的一个封装,为了在请求方式时方便的访问到方法、方法参数、方法上的注解、所属的类、方法的参数、方法参数的注解等。

public class HandlerMethod {

	// Object类型,既可以是个Bean,也可以是个BeanName
	private final Object bean;
	// 如果是BeanName,拿就靠它拿出Bean实例了~
	@Nullable
	private final BeanFactory beanFactory;
	private final Class<?> beanType; // 该方法所属的类
	private final Method method; // 该方法本身
	private final Method bridgedMethod; // 被桥接的方法,如果method是原生的,它的值同method
	// 封装方法参数的类实例,**一个MethodParameter就是一个入参**
	// MethodParameter也是Spring抽象出来的一个非常重要的概念
	private final MethodParameter[] parameters;
	@Nullable
	private HttpStatus responseStatus; // http状态码(毕竟它要负责处理和返回)
	@Nullable
	private String responseStatusReason; // 如果状态码里还要复述原因,就是这个字段  可以为null
……

它虽然可以封装这么多东西(持有Method),但是它没有invoke调用方法的能力,只能自己手动执行。

可以看到它的子类InvocableHandlerMethod,命名就可以看出增加了invoke方法。

虽然它提供了调用了能力,但是它却依旧还没有和Servlet的API绑定起来,毕竟使用的是Spring自己通用的的NativeWebRequest

而子类ServletInvocableHandlerMethod才是真正为servlet编写的类,并且还增加了返回值和响应状态码的处理

 HandlerMethodReturnValueHandler接口的调用过程

HandlerMethodArgumentResolver参数注入参考:https://blog.csdn.net/sumengnan/article/details/113774179

直接从RequestMappingHandlerAdapter开始,调用链如下:

1、由于下面要用到RequestMappingHandlerAdapter的returnValueHandlers属性,这里先说一下:

RequestMappingHandlerAdapter类实现了InitializingBean接口,了解过bean生命周期都知道,在bean实例化时会执行afterPropertiesSet方法,如图:

执行getDefaultReturnValueHandlers方法,初始化下面的方法参数解析器,还有初始化绑定解析器和返回值处理器就不说了:

之后创建HandlerMethodReturnValueHandlerComposite对象并把这些解析器add进去。

2、调用Handler前的准备

创建一个ServletInvocableHandlerMethod类,并把上面的returnValueHandlers属性放进去。

还有准备ModelAndViewContainer,你可以认为是上下文容器,它主要是承担着整个请求过程中数据的传递工作,例如:处理保存Model和View。

还有AsyncWebRequest和SpringMVC中异步请求有关。异步参考:https://www.cnblogs.com/deityjian/p/11503218.html

3、执行ServletInvocableHandlerMethod的invokeAndHandle方法

invokeForRequest:是进行Handler的参数注入和调用Handler的功能

主要关注handleReturnValue方法,这个才是对Handler的返回值的处理

4、HandlerMethodReturnValueHandlerComposite(组合模式)准备处理Handler返回值

挨个通过各HandlerMethodReturnValueHandler接口实现类的supportsReturnType方法去判断是否支持此返回值处理

5、找到真正处理Handler返回值的类:RequestResponseBodyMethodProcessor

setRequestHandled方法表示此类可以处理返回值,后续则不需要再此处理了

6、writeWithMessageConverters方法的作用使用消息转换器转换消息后写入response,部分代码如下

挨个查询消息转换器,通过canWrite方法判断是否支持,若是支持则使用write方法写。

GenericHttpMessageConverter消息转换器的接口实现如下:

springMVC默认的消息转换器是:MappingJackson2HttpMessageConverter

为什么?

因为在springboot自动配置中配置了消息转换器,如图:

7、write方法是AbstractGenericHttpMessageConverter的,继续会调用writeInternal方法

8、这个writeInternal方法是各个不同的转换器实现的主要方法

jackson框架是使用ObjectWriter进行序列化和反序列化的

最终jackson通过把序列化的数据写入servletResponse的OutputStream()方法缓冲区,再通过flush方式把数据返回给了客户端

猜你喜欢

转载自blog.csdn.net/sumengnan/article/details/114134909