Springboot请求映射原理
springboot中的spring-boot-starter-web还是使用的spring-mvc。而spring-mvc中处理所有的请求的入口就是DispatcherServlet.
而DispatcherServlet就一定要重写doGet或者doPost,但是在springboot中的DispatcherServlet中没有这两个方法。
而是在DispatcherServlet的父类FrameworkServlet中找到了。
1 2 3 4 5 6 7 8 9 10 11 12 | @Override protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } |
看出不管是doGet还是doPost都是执行的processRequest这个方法。
processRequest方法
1 protected final void processRequest(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 4 long startTime = System.currentTimeMillis(); 5 Throwable failureCause = null; 6 7 LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext(); 8 LocaleContext localeContext = buildLocaleContext(request); 9 10 RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes(); 11 ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes); 12 13 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 14 asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor()); 15 16 initContextHolders(request, localeContext, requestAttributes); 17 18 try { 19 doService(request, response); 20 } 21 catch (ServletException | IOException ex) { 22 failureCause = ex; 23 throw ex; 24 } 25 catch (Throwable ex) { 26 failureCause = ex; 27 throw new NestedServletException("Request processing failed", ex); 28 } 29 30 finally { 31 resetContextHolders(request, previousLocaleContext, previousAttributes); 32 if (requestAttributes != null) { 33 requestAttributes.requestCompleted(); 34 } 35 logResult(request, response, failureCause, asyncManager); 36 publishRequestHandledEvent(request, response, startTime, failureCause); 37 } 38 }
主要看第19行的doService(request, response);方法,而这个方法中又调用了核心的doDispatch方法,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null ; boolean multipartRequestParsed = false ; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null ; Exception dispatchException = null ; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. mappedHandler = getHandler(processedRequest); |
通过getHandler方法拿到对应可以处理当前请求的mappedHandler;
1 2 3 4 5 6 7 8 9 10 11 | 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 ; } |
debug之后发现会有如下几个HandlerMapping;
而我们需要找到的是
RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。
当有请求进来时,会循环尝试所有的HandlerMapping看是否有请求信息。
- 如果有就找到这个请求对应的handler
- 如果没有就是下一个 HandlerMapping
Springboot请求映射原理就是其实就是查询对应HandlerMapping进行请求处理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix