LoginSignup
0
0

More than 3 years have passed since last update.

Spring MVC: how framework maps URI to bean

Last updated at Posted at 2021-07-01

What is org.springframework.web.servlet.HandlerMapping interface?

From the document from Spring Framework, it says "Interface to be implemented by objects that define a mapping between requests and handler objects.". In my notice board example application, following bean is created when started.

Order Bean Name Class Where it created
2147483647 welcomePageHandlerMapping org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration.welcomePageHandlerMapping(ApplicationContext, FormattingConversionService, ResourceUrlProvider)
2147483646 resourceHandlerMapping org.springframework.web.servlet.handler.SimpleUrlHandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping()
2 beanNameHandlerMapping org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.beanNameHandlerMapping()
0 requestMappingHandlerMapping org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.EnableWebMvcConfiguration.requestMappingHandlerMapping()
-2147483647 faviconHandlerMapping org.springframework.web.servlet.handler.SimpleUrlHandlerMapping org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.FaviconConfiguration.faviconHandlerMapping()

requestMappingHandlerMapping handles bean class which have org.springframework.web.bind.annotation.RequestMapping annotation.

How I know this? Please refer to here.

When it been loaded

First, beans are created by ApplicationContext instance.

Then when org.springframework.web.servlet.DispatcherServlet instance is created and during initialization, org.springframework.web.servlet.DispatcherServlet.initHandlerMappings(ApplicationContext) is called and all bean with org.springframework.web.servlet.HandlerMapping interface will been lookup. Its reference will be saved into DispatcherServlet's internal structure. Following is related code.

/**
 * Initialize the HandlerMappings used by this class.
 * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace,
 * we default to BeanNameUrlHandlerMapping.
 */
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<>(matchingBeans.values());
            // We keep HandlerMappings in sorted order.
            AnnotationAwareOrderComparator.sort(this.handlerMappings);
        }
    }
    else {
        ...
    }
    ...
}

Look up which bean handles particular URI

In method org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) you can see how Spring MVC actually handle a request. The code which lookup URI bean mapping is

mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
    noHandlerFound(processedRequest, response);
    return;
}

And in method org.springframework.web.servlet.DispatcherServlet.getHandler(HttpServletRequest), request will be passed into list of instances with org.springframework.web.servlet.HandlerMapping interface which is built before. If mapping is found in one instance, lookup will be stopped and org.springframework.web.servlet.HandlerExecutionChain will be returned. Following is the code.

/**
 * Return the HandlerExecutionChain for this request.
 * <p>Tries all handler mappings in order.
 * @param request current HTTP request
 * @return the HandlerExecutionChain, or {@code null} if no handler could be found
 */
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        for (HandlerMapping mapping : this.handlerMappings) {
            HandlerExecutionChain handler = mapping.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
    }
    return null;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0