[SpringMVC source code analysis] HandlerMethodReturnValueHandler return value processor

 HandlerMethodReturnValueHandler is a processing interface for Handler return values

Its implementation class is as follows:

  

What we commonly use is the RequestResponseBodyMethodProcessor implementation class : it is used to process the annotation @RequestBody method (of course @RestController also counts)

RequestResponseBodyMethodProcessor can handle both @RequestBody return value and @RequestBody parameter injection.

 

HandlerMethod class

It is an encapsulation of the Handler method, in order to conveniently access the method, method parameters, method annotations, class to which it belongs, method parameters, annotations of method parameters, etc. when requesting methods .

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
……

Although it can encapsulate so many things (holding Method), it does not have the ability to invoke methods and can only be executed manually by itself.

You can see its subclass InvocableHandlerMethod , naming you can see that the invoke method has been added.

Although it provides the ability to call, it still has not been Servletbound to the API, after all, it uses its Springown universalNativeWebRequest

The subclass ServletInvocableHandlerMethod is the real class written for servlet, and it also adds the processing of return value and response status code

 

 The calling process of HandlerMethodReturnValueHandler interface

HandlerMethodArgumentResolver parameter injection reference: https://blog.csdn.net/sumengnan/article/details/113774179

Starting directly from RequestMappingHandlerAdapter, the call chain is as follows:

1. Since the returnValueHandlers property of RequestMappingHandlerAdapter is used below, let's talk about it first:

The RequestMappingHandlerAdapter class implements the InitializingBean interface. If you know the bean life cycle, you know that the afterPropertiesSet method will be executed when the bean is instantiated, as shown in the figure:

Execute the getDefaultReturnValueHandlers method, initialize the following method parameter parser, and initialize the binding parser and return value processor.

Then create a HandlerMethodReturnValueHandlerComposite object and add these parsers.

 

2. Preparation before calling Handler

Create a ServletInvocableHandlerMethod class and put the returnValueHandlers attribute above.

There is also the preparation of ModelAndViewContainer, which you can think of as a context container, which is mainly responsible for the transfer of data during the entire request process, such as processing and saving Model and View.

There is also AsyncWebRequest related to asynchronous requests in SpringMVC. Asynchronous reference: https://www.cnblogs.com/deityjian/p/11503218.html

3. Execute the invokeAndHandle method of ServletInvocableHandlerMethod

invokeForRequest: is the function of injecting Handler parameters and calling Handler

Mainly focus on the handleReturnValue method, this is the processing of the return value of the Handler

 

4. HandlerMethodReturnValueHandlerComposite (combined mode) is ready to process Handler return value

One by one through the supportsReturnType method of each HandlerMethodReturnValueHandler interface implementation class to determine whether this return value processing is supported

5. Find the class that actually handles the return value of the Handler: RequestResponseBodyMethodProcessor

The setRequestHandled method indicates that this class can handle the return value, and there is no need to deal with it later

6. The role of the writeWithMessageConverters method. Use the message converter to convert the message and write the response. Part of the code is as follows

Query the message converter one by one, and judge whether it is supported by the canWrite method, and if it is supported, use the write method to write.

The interface implementation of GenericHttpMessageConverter message converter is as follows:

The default message converter of springMVC is: MappingJackson2HttpMessageConverter

why?

Because the message converter is configured in the springboot automatic configuration, as shown in the figure:

 

7. The write method is AbstractGenericHttpMessageConverter, and the writeInternal method will continue to be called

8. This writeInternal method is the main method implemented by different converters

The jackson framework uses ObjectWriter for serialization and deserialization

Finally, Jackson writes the serialized data into the buffer of the OutputStream() method of servletResponse, and then returns the data to the client through flush.

 

Guess you like

Origin blog.csdn.net/sumengnan/article/details/114134909