HandlerMapping, HandlerAdapter, and springmvcmapping in Spring MVC

Source: Internet
Author: User

HandlerMapping, HandlerAdapter, and springmvcmapping in Spring MVC
Relationship between HandlerMapping and HandlerAdapter in Spring MVC

I recently discussed a question about spring mvc with my colleagues. I asked my colleagues what is the relationship between HandlerMapping and HandlerAdapter? Although spring mvc is not a short time, there are only two keywords that can be used in an instant:

  • @ RequestMapping: This is often used. The action method under each Controller generally defines a unique url path. After an HTTP request is sent to the server, the server searches for the action under the Controller to be executed based on the url. I understand it as a routing relationship between the url and java code.
@ RequestMapping (value = "/bss/{priceId}", method = RequestMethod. GET) public ValueResult <ProductPrice> getProductPrice (HttpServletRequest request, @ Min (value = 1, message = "priceId illegal") @ PathVariable final long priceId) {// omitted}
  • HandlerInterceptor, which is also frequently used for Request Interception.

Although the above two keywords are related to the problem, they are obviously not the main one. The core is what the two interfaces do and what interaction they have. Therefore, we can start to debug the call process of spring mvc from a request to analyze their functions and relationships.

Spring MVC configuration files:
  • Application-level applicationContext. xml, usually load non-web configurations, such as database configuration and redis configuration.
  • Web-level mvc-dispatcher-servlet.xml, here focused on mvc configuration.
XmlWebApplicationContext context = new XmlWebApplicationContext();context.setConfigLocations(new String[]{"classpath*:applicationContext.xml","classpath*:spring/mvc-dispatcher-servlet.xml"});ServletContextHandler spingMvcHandler = new ServletContextHandler();spingMvcHandler.setContextPath(appConfig.getContext());spingMvcHandler.addEventListener(new ContextLoaderListener(context));spingMvcHandler.addServlet(new ServletHolder(new DispatcherServlet(context)), "/*");

Here, I will refer to the diagram of Dr. Zhang Tao to illustrate the functions and relationships of the above two configurations:

Two core classes
  • ContextLoaderListener
    This is mainly used to load ApplicationContext information when starting the web container. It is used to create the ROOT ApplicationContext and can receive XML-type information, such as XmlWebApplicationContext, it loads configuration information from the XML configuration file.

This article does not focus on this point.

  • DispatcherServlet
    It is also called a front-end controller. It is the unified access entry of Spring MVC and is responsible for assigning duties and debugging work. Due to its complicated functions, it only cares about the content of HandlerMapping and HandlerAdaper. The following are initialization functions, including HandlerMapping and HandlerAdaper initialization.
@ Overrideprotected void onRefresh (ApplicationContext context) {initStrategies (context);}/*** Initialize the strategy objects that this servlet uses. * <p> May be overridden in subclasses in order to initialize further strategy objects. */protected void initStrategies (ApplicationContext context) {// other initialization initHandlerMappings (context); initHandlerAdapters (context); // other initialization}

InitHandlerMappings, mainly called BeanFactoryUtils. beansOfTypeIncludingAncestors, one of the most important HandlerMapping is RequestMappingHandlerMapping. We add @ RequestMapping comments to the Controller to use it. The system registers the configured RequestMapping information, detailed data parameters: mappingRegistry contains all request routing information.

The Code is as follows:

Private void initHandlerMappings (ApplicationContext context) {this. handlerMappings = null; if (this. detectAllHandlerMappings) {// Find all HandlerMappings in the ApplicationContext, including ancestor contexts. map <String, HandlerMapping> matchingBeans = BeanFactoryUtils. beansOfTypeIncludingAncestors (context, HandlerMapping. class, true, false); if (! MatchingBeans. isEmpty () {this. handlerMappings = new ArrayList <HandlerMapping> (matchingBeans. values (); // We keep HandlerMappings in sorted order. annotationAwareOrderComparator. sort (this. handlerMappings) ;}}// omitting the default logic before loading not all}

DispatcherServlet core method: doDispatch, three important steps:

  • GetHandler is used to obtain the page processor. The common point is to obtain the Controller that executes the request, including the method information and method parameters.
  • GetHandlerAdapter: gets HandlerAdapter. It contains a handle method that calls a real page processor to process requests and returns a ModelAndView. HandlerAdpter provides some common processing methods, such as message transfer and parameter processing. For details, see the figure below: argumentResolvers in it can be used to process request parameters, and messageConverts is used to convert messages.

  • HandlerAdapter. handle: executes the Processing request of the real page processor.
Request sequence diagram (only pay attention to HandlerMapping and HandlerAdapter)

DoDispath obtains the page processor, obtains the corresponding HanlerAdapter Based on the page processor, and finally calls the method of the page processor by HanlerAdaper.

Protected void doDispatch (HttpServletRequest request, HttpServletResponse response) throws Exception {// initialization omitting try {ModelAndView mv = null; Exception dispatchException = null; try {processedRequest = checkMultipart (request ); multipartRequestParsed = (processedRequest! = Request); // Determine handler for the current request. mappedHandler = getHandler (processedRequest); if (mappedHandler = null | mappedHandler. getHandler () = null) {noHandlerFound (processedRequest, response); return;} // Determine handler adapter for the current request. handlerAdapter ha = getHandlerAdapter (mappedHandler. getHandler (); // other logic is omitted // Actually invoke the handler. mv = ha. handle (processedRequest, response, mappedHandler. getHandler (); // other logic omitted} catch (Exception ex) {dispatchException = ex;} processDispatchResult (processedRequest, response, mappedHandler, mv, dispatchException );} // exception logic omitted}

The specific calling logic is complex. Only the sections with HandlerMapping and HandlerAdaper are selected. The sequence diagram is as follows:

Reference

Http://jinnianshilongnian.iteye.com/blog/1602617

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.