Analysis of RequestMapping in springmvc, mvcrequestmapping
When studying the source code, we should look at the top layer, so let's first look at the definition of this interface:
Package org. springframework. web. servlet; import javax. servlet. http. HttpServletRequest ;/**
1. Define an interface for ing requests and processors.
Developers can also implement this interface by themselves, although this is not necessary, because springmvc currently provides a lot of implementations, the most typical is
BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping, RequestMappingHandlerMapping, and so on. In previous versions, if we didn't display the settings
This is the first two RequestMapping, but the current version is BeanNameUrlHandlerMapping and DefaultAnnotationHandlerMapping. If the mvc: annotation-driven annotation is configured
RequestMappingHandlerMapping
)
2. The ing result can contain 0 or more interceptors. preHandle is executed before the execution processor. If the interceptor returns true, the logic of the processor is executed.
At the same time, the ability to process parameters is also very powerful. We can define RequestMapping to process various parameters (but obviously we can directly define the parameter converter without doing so)
3. Because the system can set multiple HandlerMapping, we should implement the Ordered interface to indicate their respective priorities. The smaller the value, the higher the priority. The default value is Integer. MAX_VALUE. The priority is the lowest.
*/
Public interface HandlerMapping {// This attribute indicates the url-specific HandlerMapping String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping. class. getName () + ". pathWithinHandlerMapping "; // HanlderMapping String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping with the highest request matching degree. class. getName () + ". bestMatchingPattern "; // whether class-level mappings are supported. For example, DefaultAnnotationHandlerMapping uses this attribute to indicate class-level mappings. (If we do not set it, it is supported by default.
// @ See AnnotationMethodHandlerAdapter $ ServletHandlerMethodResolver. useTypeLevelMapping () String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping. class. getName () + ". introspectTypeLevelMapping "; // It is also the KEY name in the request. When the value is map, it is stored in the String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping. class. getName () + ". uriTemplateVariables "; // similar to the preceding one, but the classes are different in that they store Matrix Variable (that is, the value that can be used; separated) String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping. class. getName () + ". matrixVariables "; // The media type supported by HandlerMapping: String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping. class. getName () + ". producibleMediaTypes ";/**
The only method of this class, according to the single responsibility principle, we understand that the only responsibility of HandlerMapping is to make a request according to different policies.
Finally, it is converted into an object like HandlerExecutionChain. It is not an interface but a class. This class encapsulates the processor and a series
The interceptor and acts as a proxy for the front and back processing of this series of processes.
*/HandlerExecutionChain getHandler (HttpServletRequest request) throws Exception ;}
Through the above analysis, we have understood the purpose of HandlerMapping. The purpose is to construct an environment for subsequent operations through HandlerMapping after a request comes, this includes the supported media types we have defined, various parameters that come with requests, and interceptor set in the system. This step is equivalent to springmvc.
Let's look at a basic abstract class. This class is to provide some basic facilities and leave a major job for the subclass for implementation. This is AbstractHandlerMapping. Because of this many methods, I will not post the class. I will mainly analyze the functions implemented by this class, as well as where we focus on and where to expand it.
This abstract class not only implements HandlerMapping, but also implements the Ordered interface. This interface prompts in HandlerMapping that we are defining our own order. It also inherits the Basic settings class of spring to provide some references such as ServletContext and WebApplicationContext. Therefore, if we want to implement our own HandlerMapping, we recommend that this abstract class be OK.
Let's look at one of the most important methods:
@Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } return getHandlerExecutionChain(handler, request); }
Actually getHandlerInternal (...) is a template method that allows subclass to return the processor. If it is null, the default processor is returned. but if we want to set the default processor, we need to inject it ourselves. The default value is null. If we provide a string-type processor, it will search for the processor in the current container. It is strange that I found that this is also done in the subclass = !, And the code is written by the same buddy. It seems that we do not quite understand the idea of the great gods. In addition, the final getHandlerExecutionChai is very important, and the interceptor is obtained in this method. in addition to these important points, this abstract class also leaves a child: extendInterceptors (List <Object> interceptors) to the subclass to perform some operations on the interceptor.
The next step is to process different HandlerMapping types. However, HandlerExecutionChain is returned, including the processor and interceptor.