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的对象是同一个。