springmvc根据请求uri获取handlermapping源码

springmvc根据请求uri获取handlermapping源码

org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler

org.springframework.web.servlet.DispatcherServlet#getHandler

    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 = obtainApplicationContext().getBean(handlerName);
        }

        HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

        if (logger.isTraceEnabled()) {
            logger.trace("Mapped to " + handler);
        }
        else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
            logger.debug("Mapped to " + executionChain.getHandler());
        }

        if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
            CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
            CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
            config = (config != null ? config.combine(handlerConfig) : handlerConfig);
            executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
        }

        return executionChain;
    }

此处定义个三个controller,分别采用springmvc实现controller的三种方式。如下所示。

@Component("/handlercontroller.do")
public class HandlerController implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("111");
    }
}

@Component("/implController.do")
public class ImplController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("实现Controller接口");
        return new ModelAndView("index");
    }
}

@Controller
public class TestController {


    /**
     * 访问普通的字符串,试图解析器会解析成对应的页面
     * @return
     */
    @RequestMapping("/str.do")
    public Object Test(){
        return "index";
    }

    /**
     * 因为返回值是一个对象,所以如果不做特殊处理,则试图解析器无法解析
     * 对象嵌套是一个难点
     * @param name
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/model.do")
    @ResponseBody
    public Object modeltest(String name, HttpServletRequest request, HttpServletResponse response){
        System.out.println("调用了modeltest");
        String req_name = request.getParameter("name");
        Map hashMap = new HashMap<>();
        hashMap.put("key", "value");
        return hashMap;
    }
}

现在依次测试

断点:

 

 

 先访问:http://localhost/model.do

 

 

 

从getHandlerInternal(request)已经获取到handler

 

第二次测试地址:http://localhost/handlercontroller.do

进行代码跟踪发现程序在遍历三个handleMappings,分别是:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RouterFunctionMapping

此时RequestMappingHandlerMapping未空,所以遍历到BeanNameUrlHandlerMapping,因为这次访问的uri的定义方式是实现HttpRequestHandler接口。

 

 

此时已经找到了匹配的handler。

第三次访问地址:http://localhost/implController.do

 

 

 

可以看到,与第二次访问所获取handler的对象是同一个。

 

posted @ 2021-01-14 21:35  Java民工陆小凤  阅读(392)  评论(0编辑  收藏  举报