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进行请求处理

 

posted @   swayer  阅读(232)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示