文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

拼多多一面:聊聊 Spring MVC 的工作原理!

2024-11-29 17:42

关注

Spring MVC(Model-View-Controller)是 Spring框架中用于构建 Web应用程序的模块之一,它遵循经典的MVC设计模式,将应用程序的不同方面分离,以实现更好的组织和可维护性。下面,我们将从架构,工作流程,核心组件分析等角度来详细分析 Spring MVC的工作原理。

Spring MVC的架构

Spring MVC的架构主要由以下几个核心组件构成:

整体结构如下图:

Spring MVC的工作流程

Spring MVC的请求处理流程可以分为以下几个步骤:

DispatcherServlet详解

DispatcherServlet 是 Spring MVC 的核心组件之一,它负责处理所有进入的 HTTP 请求,并将它们分发到合适的处理器(控制器)。由于 DispatcherServlet 是一个复杂的类,这里只是摘要了 DispatcherServlet 核心源码进行分析。

1. DispatcherServlet 初始化

DispatcherServlet 在初始化过程中会加载 Spring 应用上下文,并初始化一些关键组件,如 HandlerMapping、HandlerAdapter、ViewResolver 等。

@Override
protected void onRefresh(ApplicationContext context) {
    // 初始化策略模式中的各种组件
    initStrategies(context);
}

initStrategies 方法用于初始化请求处理所需的各种策略组件:

protected void initStrategies(ApplicationContext context) {
    initMultipartResolver(context);  // 文件上传解析器
    initLocaleResolver(context);     // 本地化解析器
    initThemeResolver(context);      // 主题解析器
    initHandlerMappings(context);    // 处理器映射
    initHandlerAdapters(context);    // 处理器适配器
    initHandlerExceptionResolvers(context); // 异常解析器
    initRequestToViewNameTranslator(context); // 视图名称翻译器
    initViewResolvers(context);      // 视图解析器
    initFlashMapManager(context);    // Flash映射管理器
}

2. 请求处理流程

DispatcherServlet 的核心请求处理逻辑在 doDispatch 方法中实现。该方法负责将请求分发到合适的处理器,并完成请求的处理。

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

    // 检查请求是否为文件上传请求
    if (isMultipartRequest(request)) {
        // 处理文件上传请求
        processedRequest = checkMultipart(request);
        multipartRequestParsed = (processedRequest != request);
    }

    // 确定请求的处理器
    mappedHandler = getHandler(processedRequest);
    if (mappedHandler == null || mappedHandler.getHandler() == null) {
        noHandlerFound(processedRequest, response);
        return;
    }

    // 确定处理器适配器
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

    // 处理请求并返回ModelAndView
    ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    // 渲染视图
    processDispatchResult(processedRequest, response, mappedHandler, mv, null);
}

3. 处理器映射和适配

DispatcherServlet 使用 HandlerMapping 来查找合适的处理器,并使用 HandlerAdapter 来调用处理器的方法。

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    for (HandlerMapping hm : this.handlerMappings) {
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
    return null;
}

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    for (HandlerAdapter ha : this.handlerAdapters) {
        if (ha.supports(handler)) {
            return ha;
        }
    }
    throw new ServletException("No adapter for handler [" + handler + "]");
}

4. 视图解析和渲染

DispatcherServlet 使用 ViewResolver 来解析视图名称并渲染视图。

protected void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
                                     HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception)
        throws Exception {

    if (mv != null && !mv.wasCleared()) {
        render(mv, request, response);
    }
}

protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
    View view;
    String viewName = mv.getViewName();
    if (viewName != null) {
        // 使用ViewResolver解析视图名称
        view = resolveViewName(viewName, mv.getModelInternal(), request);
    } else {
        view = mv.getView();
    }
    if (view != null) {
        // 渲染视图
        view.render(mv.getModelInternal(), request, response);
    }
}

5. 异常处理

DispatcherServlet 也具有处理异常的能力,它会使用配置的异常解析器来处理请求过程中发生的异常。

protected void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
                                     HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception)
        throws Exception {

    if (exception != null) {
        if (exceptionResolvers != null) {
            for (HandlerExceptionResolver resolver : this.exceptionResolvers) {
                ModelAndView exMv = resolver.resolveException(request, response, mappedHandler.getHandler(), exception);
                if (exMv != null) {
                    mv = exMv;
                    break;
                }
            }
        }
    }
    
    if (mv != null && !mv.wasCleared()) {
        render(mv, request, response);
    }
}

HandlerMapping和Controller

在 Spring MVC 框架中,HandlerMapping 和 Controller 是两个非常重要的组件,它们负责请求的路由和处理,下面我们详细分析这两个组件的作用及其工作机制。

1.HandlerMapping

HandlerMapping 是 Spring MVC 中的一个接口,它的主要作用是根据请求的 URL、HTTP 方法等信息将请求映射到具体的处理器(通常是一个控制器方法)。HandlerMapping 的存在使得应用程序可以灵活地配置请求路径与控制器之间的映射关系。

(1) 常见的 HandlerMapping 实现

BeanNameUrlHandlerMapping:

RequestMappingHandlerMapping:

SimpleUrlHandlerMapping:

(2) HandlerMapping 的工作流程

2.Controller

Controller 是 Spring MVC 中用于处理请求的组件。它负责接收请求参数、调用业务逻辑,并返回视图名称或响应数据。Controller 的设计使得业务逻辑与请求处理分离,便于维护和扩展。

(1) Controller 的类型

注解驱动的控制器:

传统的控制器接口:

(2) Controller 的工作流程

视图的渲染

在视图渲染阶段,视图对象根据Model中的数据进行渲染,生成最终的输出结果。视图的类型可以多种多样,如HTML、JSON、XML等。常见的视图技术包括:

总结

本文,我们分析了 Spring MVC的原理,因为其涉及的内容比较多,所以在面试过程中,我们要抓大放小,先掌握其High Level的设计思想,Spring MVC的核心思想是通过控制器来处理请求,将请求数据与业务逻辑分离,并将最终的响应结果交给视图层进行展示。

在掌握了High Level的设计思想之后,我们再去分析它的几个核心组件,如 DispatcherServlet、HandlerMapping、Controller、ViewResolver等。

另外,在日常工作中,除了应付面试,我们应该更多地去了解 SpringMVC的底层原理,可以毫不夸张地说,只要是和业务的 CRUD打交道,几乎离不开 Spring MVC,所以多了解其原理,可以帮助我们更深入地掌握它,在日常使用中才能更加的游刃有余!

来源:猿java内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯