Parsing @ RequestMapping

Question: What would we do if we were to implement an MVC that could route to a method via a URL?

** A: ** We will first maintain a relationship between a URL and the Controller and its specific execution method, and then find the corresponding Controller when called and execute the corresponding method.

Registers the mapping between urls and methods.

The following figure shows the execution logic

The code sequence diagram is shown below

Sequence diagrams focus on code parsing

  1. The processCandidateBean(beanName) is used to check whether the controller has the @controoer annotation or the @requestmapping annotation. Whether the bean is already registered in the context, etc.

  2. Core executive functions are as follows:

1. The method meeting the conditions is executed

`getMappingForMethod(Method,Class<? >) `

Construct an object that performs the mapping between methods and URLS. This object is typically RequestMappingInfo

Note that sometimes we have @requestMapping on the Controller Bean and sometimes we don’t, so this place also has to parse @requestMapping on the Controller Bean and merge it if it does

2. Place the required objects in a Map, where the generic T is RequestMappingInfo,

3. Iterate over the Map and register the information in it. In fact, the information is refined and placed in the respective memory Map. This registration process converts RequestMappingInfo to HandlerMethod, which is handled in the DispartcherServlet as shown below, with the core operations in the red box

The above steps will basically be the URL and method mapping relationship maintenance, the overall operation is relatively simple, method invocation is not more complex, only used a template method mode basic implementation are in the abstract class

AbstractHandlerMethodMapping are completed.

Call @requestMapping from the URL

The following two sequence diagrams illustrate the implementation of @requestMapping in Spring MVC

Sequence diagram key node code explanation

The first code in the sequence diagram is as follows. GetHandlerInternal obtains HandlerMethod which is placed in the configuration class Map at the time of system startup. The implementation is very simple, and HandlerMethod is found by URL from the global Map of Registry previously configured

This code gets the adapter that executes the HandlerMethod. All operations are done through the adapter class.

** This leaves a question: ** Why does Spring need to create an adapter instead of calling the Controller in the HandlerMethod directly via invoke?

After 3, before 4, you’re dealing with the environment, parsing parameters, etc., and you’re really doing 4

The logic to perform is to parse the parameters and then call the proxy object through a dynamic proxy

That’s the whole process of parsing @RequestMapping and calling @RequestMapping. There are a lot of details I haven’t covered yet, such as cross-domain, asynchronous, parameter resolution, class name resolution, exception handling, etc., but these are all things that make the application more robust.

Parsing @ RequestBody

Question: Also, if we were to design the parsing process, what would we do?

A: I first verify that the @requestBody parameter is required, then convert the request parameter to the corresponding parameter type, and then pass the parameter to execute

Reality: It’s pretty much the same, but the actual implementation logic is much more robust. One difference is that it parses the parameter first. If no parameter is parsed, it determines whether the parameter is required.

Follow the traditional line sequence diagram

Core logic code parsing

The core logic of the sequence diagram above has been boxed in red

1: it’s very important to set the HandlerMethodArgumentResolverComposite RequestMappingHandlerAdapter into ServletInvocableHandlerMethod

Here’s a question:

Question: * * * * why need to use HandlerMethodArgumentResolverComposite HandlerMethodArgumentResolver without directly use?

In a real project, the forms of parameter passing vary, so how can we achieve maximum compatibility? Through this HandlerMethodArgumentResolverComposite is actually the adornment of HandlerMethodArgumentResolver class, to enrich function

, its all HandlerMethodArgumentResolver on their private property argumentResolvers this collection.

HandlerMethodArgumentResolver inheritance figure

In practice, different scenarios use their different implementation classes to parse the parameters

Find the parameter parser that actually parses @RequestBody

In the above said to the adornment of the class has a private getArgumentResolver (parameter) to find the real parsing parameters HandlerMethodArgumentResolver

Different parsers parse logic quite differently,

The parameter parser to parse @requestBody is

RequestResponseBodyMethodProcessor, HTML code is as follows, is essentially to its parent class AbstractMessageConverterMethodArgumentResolver in processing,

Parse the @requestParam @pathVariable annotations based on the above logic

Also HandlerMethodArgumentResolver subclasses

Parsing @ PathVariable PathVariableMapMethodArgumentResolver

Parsing @ RequestParam RequestParamMethodArgumentResolver

This is the whole logic to parse @requestMapping and @requestBody @requestParam @pathVariable

Come with the official SPRING MVC documentation