SpringMVC面试题总结「建议收藏」

SpringMVC面试题总结「建议收藏」前言:SpringMVC的面试题常见的也就那几种,本文我打算分为两个方向为大家介绍SpringMVC的面试题。第一部分将从源码的执行的角度分析SpringMVC(以后简称MVC)第二部分将从面试官常问的SpringMVC面试题取介绍SpringMVC源码介绍1.http://localhost:8000/hello这个路径的执行流程是怎么走的流程大致分析一下:首先会请求会进入前…

大家好,又见面了,我是你们的朋友全栈君。

前言:SpringMVC的面试题常见的也就那几种,本文我打算分为两个方向为大家介绍SpringMVC的面试题。

第一部分将从源码的执行的角度分析SpringMVC(以后简称MVC)

第二部分将从面试官常问的SpringMVC面试题取介绍

SpringMVC源码介绍

1.http://localhost:8000/hello这个路径的执行流程是怎么走的

流程大致分析一下:首先会请求会进入前端控制器的doService方法->调用doDispatch方法->调用handle方法->这个handle方法需要从RequestMappingHandlerAdapter的父类找到AbstractHandlerMethodAdapter里面的handle方法,这个方法又调用RequestMappingHandlerAdapter的handleInternal方法->调用this的invokeHandlerMethod->invokeAndHandle->invokeForRequest->doInvoke方法->doInvoke里面调用this.getBridgedMethod().invoke其中this.getBridgedMethod()这个就是controller里面的那个方法,这就利用了反射机制,这就是MVC的执行流程,期间经历了RequestMappingHandlerAdapter这个处理器适配器,ServletInvocableHandlerMethod Servlet处理控制方法,InvocableHandlerMethod执行方法反射这主要的三个类

下面将用截图代码分析MVC的执行流程

首先进入前端控制器的doservice方法,调用doDispatch方法

SpringMVC面试题总结「建议收藏」xa

下面看下doDispatch方法干了啥事吧

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            try {
                //返回modelAndView对象
                ModelAndView mv = null;
                Object dispatchException = null;
                //做检查
                try {
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }
                    //这个比较重要,创建一个请求的处理器适配器
                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = "GET".equals(method);
                    if (isGet || "HEAD".equals(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                        }

                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }

                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
                    //这个就比较重要了,调用处理器适配器来处理
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }

                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

下面我们来看下mv = ha.handle(processedRequest, response, mappedHandler.getHandler());做了什么事吧

SpringMVC面试题总结「建议收藏」

说白了,这就是调用了RequestMappingHandlerAdapter里面的handleInternal方法

SpringMVC面试题总结「建议收藏」

可以看下invokeForRequest方法,最后调用doInvok方法

SpringMVC面试题总结「建议收藏」

第二种介绍:springmvc的流程图分析:

SpringMVC面试题总结「建议收藏」

1.用户请求进入前端控制器,调用doservice在调用doDispatch方法,调用getHandler方法,返回一个HandlerExecutionChain,里面包含一个你自己写的controller和mvc的拦截器,获得这个执行链mappedHandler之后,调用getHandlerAdapter(mappedHandler.getHandler())方法,获取适配器,这就是上图右半部分的分析,左半部分暂时未做分析

代码截图分析:

不要意思,纠正下错误,默认提供的映射器只有两种

SpringMVC面试题总结「建议收藏」

 

SpringMVC面试题总结「建议收藏」

拿到handler,来调用适配器的代码分析如下:

SpringMVC面试题总结「建议收藏」

后面的视图解析器部分以后再补充

2.映射路径的初始化源码分析

2.首先我们需要知道的是,我们写在controller里面的请求路径可是在应用程序加载启动时就被MVC加载好了的,存放到了一个Map里面。我们来分析下源码:

2.1在前端控制器中有一个initHandlerMappings方法,我们在这个方法打一个断点,程序在启动的时候就会进来

SpringMVC面试题总结「建议收藏」

2.2我们debug走到我们打断点的地方

SpringMVC面试题总结「建议收藏」

点开这些内容:

SpringMVC面试题总结「建议收藏」

我们会发现,MVC已经把对对应的关系放到了mappLookup中了,后续只需要取这个map里面取就行

3.MVC参数封装的原理分析(以最基础的类型参数封装为例)

前面的请求啥的都和前面分析的一样,我们直接看ServletInvocableHandlerMethod类里面的invoForRequest方法

SpringMVC面试题总结「建议收藏」

进去getMethodArgumentValues方法里面发现,主要是有一个argumentResove在起作用

SpringMVC面试题总结「建议收藏」

进入HandlerMethodArgumentResolverComposite类里面

SpringMVC面试题总结「建议收藏」

进入RequestParamMethodArgumentResolver这个类,通过servlet原始的封装getParamtermValues获取参数的值

SpringMVC面试题总结「建议收藏」

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150799.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月19日 下午3:00
下一篇 2022年6月19日 下午3:16


相关推荐

  • 啥是SBC_sbc是什么意思的缩写

    啥是SBC_sbc是什么意思的缩写SBC简介SBC应用SBC功能★SBC简介会话边界控制器SessionBorderController,即会话边界控制器SBC已经逐渐成为NGN和IMS网络的标准配置产品(如同Lanswitch和路由器)。也被广泛称为BAC(边界接入控制器),定位在IMS网络的ABG(accessbordergateway),解决NGN业务部署中遇到的NAT/FW穿越

    2025年10月31日
    5
  • ORA-00933: SQL 命令未正确结束

    ORA-00933: SQL 命令未正确结束java sql SQLSyntaxErr ORA 00933 SQL 命令未正确结束在数据库中语句运行完全没问题 但是在编程的时候却报这样的错误控制台看似报一大堆异常原因可能是 1 你没逗号可能没写够 仔细检查 SQL 语句 2 在写 jdbc 操作时 在进行多表关联查询时 我们通常采用分行的写法 但是需要注意在每行 sql 语句结束后与冒号之间加个空格 如图 ps 你们

    2026年3月26日
    3
  • 【ESP32接入国产大模型之腾讯混元】

    【ESP32接入国产大模型之腾讯混元】

    2026年3月13日
    2
  • pycharm换源和导入包

    pycharm换源和导入包一 换源 1 打开 pycharm 的 Setting2 选择目录 projectinter 点击小加号进行下一步 3 点击 ManageReposi 点击小加号添加源 或者点击源选中之后点击减号删除源 Python 里的 pip 是官方自带的源 国内使用 pip 安装的时候十分缓慢 所以最好是更换成中国国内的源地址 国内 pip 镜像源清华 ht

    2026年3月27日
    2
  • Microsoft Agent Framework:基于 DelegatingAIAgent 与 ChatClientAgent 的核心架构和协同范式

    Microsoft Agent Framework:基于 DelegatingAIAgent 与 ChatClientAgent 的核心架构和协同范式

    2026年3月15日
    3
  • pycharm安装教程中文_java将对象转为json

    pycharm安装教程中文_java将对象转为json#1.下载安装包下载地址(http://www.jetbrains.com/pycharm/download/#section=windows)#2.安装#3.激活选择Activationcode在http://idea.lanyus.com/获取注册码修改hosts文件,加入以下字段0.0.0.0account.jetbrains.com#4.中文界面下载语言包https://github…

    2022年8月25日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号