SpringBoot的请求映射原理
  TEZNKK3IfmPf 2023年11月13日 16 0

我们在进行web开发中,每次发请求是如何找到哪个方法去处理这个请求的。所谓请求映射的原理就是来查找源码中是如何完成这个处理的。我们知道SpringBoot中每个请求都会来到DispatcherServlet,底层还是使用SpringMVC,所以我们来看DispatcherServlet类。

该类在org.springframework.web.servlet包下:

SpringBoot的请求映射原理

进入到该类中,按快捷键“Ctrl+H”查看该类的继承树:

SpringBoot的请求映射原理

是间接继承了HttpServlet,那么一定会重写doGet()和doPost()方法,而DispatcherServlet类中没有重写doGet()和doPost()方法,那么我们就查看FrameworkServlet类中是否重写了,发现果然重写了,源码如下:

    protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.processRequest(request, response);
    }

    protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.processRequest(request, response);
    }

在两个方法中都调用了processRequest()方法,我们又查看processRequest()方法的源码,该方法的核心就是调用了doService()方法来处理请求和响应:

SpringBoot的请求映射原理

所以我们继续查看doService()方法源码,是一个抽象方法,那么我们需要看它的子类是否实现了该方法。

    protected abstract void doService(HttpServletRequest var1, HttpServletResponse var2) throws Exception;

我们又回到DispatcherServlet类,发现果然实现了doService()方法,该方法内的核心是调用了doDispatch()方法来处理请求和响应。

SpringBoot的请求映射原理

调用过程总结如下:请求首先到HttpServlet的doGet()方法,然后这个方法被FrameworkServlet类重写了,在该方法内又调用了该类的processRequest()方法,然后又调用了DispatcherServlet实现的doService()方法,最终交由doDispatcher()方法进行处理。

我们能够在doDispatcher()方法内成功打上断点,我们需要先在控制器类准备一个请求的处理,然后在浏览器访问执行:

@RestController
public class HelloController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "Hello SpringBoot";
    }
}

在doDispatcher()方法的第一行打上断点:

SpringBoot的请求映射原理

debug模式启动项目,然后在浏览器访问/hello请求

SpringBoot的请求映射原理

SpringBoot的请求映射原理

让代码走到mappedHandler.getHandler()所在行,这个方法决定哪个handler(controller中的方法)处理当前请求。然后放行,查看handler是什么。

选中mappedHandler = this.getHandler(processedRequest);右键单击出现如图面板,点击Evaluate Expression...计算结果

SpringBoot的请求映射原理

发现最终要执行的就是HelloController类中的hello()方法

SpringBoot的请求映射原理

继续将断点打在该行,但是执行到这里强行进入getHandler()方法内,查看如何生成的

SpringBoot的请求映射原理

查看handlerMappings的内容有五个处理器映射器

SpringBoot的请求映射原理

这里有一个handlerMapping,这是一个处理器映射器,SpringMVC根据它中的映射规则知道了哪个请求应该由哪个处理器(就是我们自己写的控制器类)处理。默认的handlerMapping有5个(如图),其中第一个RequestMappingHandlerMapping中保存了@RequestMapping和handler的映射规则。当我们的应用一启动,SpringMVC自动扫描所有的Controller并解析注解,把注解信息保存在handlerMapping里面。 然后通过循环遍历着5个handlerMapping,看哪个可以处理当前请求。

SpringBoot的请求映射原理

如上图,发现我们自己在controller中写的路径都存到了Map里面。然后通过mapping.getHandler(request)把请求对应的handler找到(也就是controller中对应的方法)完成映射。
SpringBoot的请求映射原理

所有的请求映射都在HandlerMapping中,SpringBoot自动配置了欢迎页的WelcomePageHandlerMapping,访问"/"就能访问到index.html,也自动配置了默认的RequestMappingHandlerMapping,当我们请求进来后,挨个尝试所有的HandlerMapping看是否有请求信息,如果有就找到这个请求对应的handler(就是我们写的控制器),如果没有则继续找下一个HandlerMapping,但如果我们需要一些自定义的映射处理,我们也可以自己通过@Bean给容器中放HandlerMapping。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
TEZNKK3IfmPf