Java八股文——Spring「SpringMVC 篇」

MVC分层介绍一下

面试官您好,MVC是一种非常经典、影响深远的软件设计模式,它的全称是Model-View-Controller。在我看来,它的核心目标就是解决早期Web开发中,业务逻辑、数据和界面显示高度耦合的问题,从而实现“各司其职、互不干扰”。

1. MVC的核心组件与职责

MVC将一个Web应用划分为三个核心部分:

  • 模型 (Model):这是应用的核心,负责处理业务逻辑管理数据
    • 在实践中,我会把它进一步细分为两部分:
      1. 业务处理逻辑 (Business Logic):这通常是我们的Service层和DAO层,负责执行具体的业务操作和数据存取。
      2. 数据载体 (Data Carrier):这通常是我们的POJO实体类或DTO,它们不包含复杂的业务逻辑,仅仅作为数据的容器,在不同层之间传递。
  • 视图 (View):这是用户直接看到的界面,负责展示数据
    • 在Web开发中,它通常是一个JSP页面、Thymeleaf模板、或者是现代前后端分离架构中的前端组件(如Vue/React)。View本身非常“笨”,它只关心如何把Model传递给它的数据渲染出来给用户看。
  • 控制器 (Controller):这是M和V之间的 “调度中心”或“交通警察”
    • 它的唯一职责就是接收用户的请求,调用合适的Model来处理这个请求,然后为处理结果选择一个合适的View来展示。它起到了承上启下的作用,确保了Model和View之间的解耦。
2. 在Spring MVC中,这个流程是如何实现的?

Spring MVC框架就是对经典MVC模式的一次完美实现。它的整个工作流程,是围绕着一个核心的前端控制器—— DispatcherServlet 来展开的。

我们可以把一次HTTP请求的旅程,看作以下几个步骤:

  1. 用户发起请求:用户在浏览器中输入URL,或者提交一个表单。
  2. DispatcherServlet接收请求 (核心调度)
    • 所有的请求首先都会被DispatcherServlet这个前端控制器拦截到。它是整个流程的“总指挥”。
  3. HandlerMapping查找处理器
    • DispatcherServlet会询问HandlerMapping(处理器映射器):“这个请求应该由哪个Controller的哪个方法来处理?”
    • HandlerMapping会根据请求的URL、HTTP方法等信息,找到匹配的、被@RequestMapping等注解标记的Controller方法。
  4. Controller执行业务逻辑
    • DispatcherServlet将请求分派给找到的Controller方法
    • 在Controller方法中,我们会去调用相应的Service层(Model的一部分) 来执行真正的业务逻辑。
  5. Model返回处理结果
    • Service层处理完毕后,会返回数据。Controller会将这些数据,连同要展示的视图信息,封装到一个 ModelAndView对象 中,并将其返回给DispatcherServlet
  6. ViewResolver解析视图
    • DispatcherServlet拿到了ModelAndView后,会把它交给 ViewResolver(视图解析器)
    • ViewResolver会根据ModelAndView中指定的逻辑视图名(比如"user/profile"),解析出真正的物理视图地址(比如/WEB-INF/jsp/user/profile.jsp)。
  7. View渲染并响应
    • 最后,DispatcherServlet会调用解析出的View(比如一个JSP页面),并将Model中的数据传递给它。
    • View负责将这些数据渲染成最终的HTML页面,然后由DispatcherServlet响应给用户的浏览器。

总结一下,MVC模式通过清晰的职责划分,将Web应用拆分为M、V、C三个松耦合的部分。而Spring MVC框架,则通过DispatcherServlet作为核心调度器,以及HandlerMappingViewResolver等一系列可配置的组件,优雅地实现了这一模式,使得我们的Web开发变得更加结构化、可维护和可扩展。

HandlerMapping 和 HandlerAdapter有了解吗?

面试官您好,HandlerMappingHandlerAdapter是Spring MVC 前端控制器(DispatcherServlet 的两个最核心、最得力的“助手”。它们共同解决了“一个进来的HTTP请求,究竟应该由谁(哪个Controller)来处理,以及该如何调用它”这个关键问题。

我喜欢用一个 “多功能插座” 的比喻来理解它们的关系:

  • DispatcherServlet:就像一个智能插座板,是所有电流(请求)的入口。
  • HandlerMapping:就像插座板上的 “寻路指示灯”
  • 各种类型的Controller:就像是来自世界各地的、有着不同形状插头的电器(比如两脚的、三脚的、圆头的)。
  • HandlerAdapter:就是插在插座板上的 “万能转换头(适配器)”
1. HandlerMapping:请求的“导航员”
  • 它的核心职责“找”。它的唯一任务,就是根据进来的HttpServletRequest信息(主要是URL),从Spring容器中找出应该处理这个请求的那个处理器(Handler)
  • 找到的是什么? 在现代Spring MVC中,这个Handler通常就是一个被@RequestMapping等注解标记的Controller方法HandlerMapping会把这个方法连同其所属的Controller实例,封装成一个HandlerExecutionChain对象(里面还包含了拦截器链),然后返回给DispatcherServlet
  • 总结HandlerMapping负责从“请求”到“处理器”的映射,它告诉DispatcherServlet:“这个请求,应该由A座的张三(某个Controller)来处理。”
2. HandlerAdapter:处理器的“万能执行器”
  • 为什么需要它?—— 适配的艺术
    • Spring MVC是一个非常灵活的框架,它不仅仅支持我们现在最常用的、基于@Controller注解的处理器。在它的发展历史中,还支持过其他类型的处理器,比如需要实现Controller接口的、或者实现HttpRequestHandler接口的古老处理器。
    • 问题来了:这些不同类型的处理器,它们的调用方式是完全不一样的。DispatcherServlet总不能写一大堆if-else来判断:“如果你是@Controller,我就这样调你;如果你是Controller接口,我就那样调你……”。这会违反“开闭原则”,代码会变得极其臃肿和难以扩展。
  • HandlerAdapter如何解决?
    • HandlerAdapter(处理器适配器)就是为了解决这个问题而生的。它运用了经典的适配器设计模式
    • Spring为每一种类型的处理器都提供了一个对应的HandlerAdapter实现。比如,RequestMappingHandlerAdapter专门负责调用被@RequestMapping注解的方法。
    • DispatcherServlet在拿到了HandlerMapping找到的Handler之后,它不会自己去调用。它会遍历容器中所有的HandlerAdapter,并询问:“你们谁能处理这种类型的Handler?”
    • 那个匹配的HandlerAdapter(比如RequestMappingHandlerAdapter)就会站出来说:“我能!”
  • 它的核心职责“执行”。它知道如何以正确的方式去调用特定类型的处理器,包括如何进行参数解析、数据绑定、调用方法、处理返回值等。最终,它会执行完处理器逻辑,并返回一个统一的ModelAndView对象给DispatcherServlet

工作流程总结

  1. 一个请求来了,DispatcherServlet(插座板)接收。
  2. DispatcherServlet问所有的HandlerMapping(寻路指示灯):“谁知道这个请求该去哪?”
  3. 一个HandlerMapping亮了,说:“我知道,应该去找那个三脚插头的电器(某个Controller方法)。”
  4. DispatcherServlet拿到了这个“三脚插头的电器”,但它自己不知道怎么供电。于是它问所有的HandlerAdapter(万能转换头):“你们谁支持三脚插头?”
  5. 一个支持三脚插头的HandlerAdapter站出来说:“我来!”
  6. 这个HandlerAdapter负责将电流(请求)正确地输送给这个电器,让它工作起来,并把工作成果(ModelAndView)返回给DispatcherServlet

通过HandlerMappingHandlerAdapter这一对精巧的组合,Spring MVC实现了极高的可扩展性。未来即使出现一种全新的处理器类型,我们只需要为其提供一个新的HandlerMappingHandlerAdapter实现,就可以无缝地集成到框架中,而无需修改DispatcherServlet的任何代码。

参考小林coding和JavaGuide

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FreeSWITCH mod_curl 和 mod_xml_rpc 测试

编辑 /usr/local/freeswitch/conf/autoload_configs/xml_rpc.conf.xml <configuration name"xml_rpc.conf" description"XML RPC"> <settings> <param name"http-port" value"8889"/> <param name&quo…

实时监控、秒级决策:镜舟科技如何重塑融资融券业务数据处理模式

融资融券业务作为证券市场的重要组成部分&#xff0c;已成为金融机构核心业务增长点和利润来源。截至 2023 年底&#xff0c;我国融资融券余额已突破 1.8 万亿元&#xff0c;业务量呈现爆发式增长。然而&#xff0c;在业务高速发展的同时&#xff0c;金融机构面临着数据处理效率…

Linux与量子计算:面向未来的架构演进

Linux与量子计算&#xff1a;面向未来的架构演进 当经典计算遇上量子革命 引言&#xff1a;量子计算时代的黎明 量子计算正从理论走向工程实践&#xff0c;Linux作为现代计算的基石&#xff0c;正在量子革命中扮演关键角色。据IBM预测&#xff0c;到2027年&#xff0c;量子优势…

Java中wait()为何必须同步调用?

在 Java 中&#xff0c;wait() 方法必须在 synchronized 方法或代码块中调用&#xff0c;主要原因如下&#xff1a; 1. 监视器锁&#xff08;Monitor&#xff09;机制 依赖对象锁&#xff1a;wait() 方法需要操作对象的监视器锁&#xff08;Monitor&#xff09;&#xff0c;调…

前端面试专栏-基础篇:4. 页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…

涨薪技术|Docker端口映射与容器互联技术

前面的推文我们学了Docker操作的常用命令,今天开始给大家分享Docker端口映射与容器互联,欢迎关注。Docker不管是程序员,架构师或者测试工程师都必须要掌握的一门主流技术。 Docker除了通过网络访问外,还提供了两个很方便的功能来满足服务访问的基本需求,一个是允许映射容…

Roboguide工作站机器人重新安装软件包

1、点击菜单栏“机器人-属性”&#xff1b; 2、点击“重新生成”&#xff1b; 3、点击“确定”&#xff1b; 4、点击“6&#xff1a;机器人选项” 5、在搜索框搜索软件包&#xff0c;或在软件包列表选择&#xff0c;勾选软件包后点击“下一步”&#xff1b; 6、点击“完成”&am…

预训练CNN网络的迁移学习(MATLAB例)

从基于大型数据集训练的神经网络中提取层&#xff0c;并基于新数据集进行微调。本例使用ImageNet中的子集进行微调。 This example retrains a SqueezeNet neural network using transfer learning. This network has been trained on over a million images, and can classif…

kali系统 windows Linux靶机入侵演练

Kali系统与Windows/Linux靶机入侵演练简介 演练概述 Kali Linux是一款专为渗透测试和网络安全评估设计的操作系统,常被安全专业人员用于合法的安全测试。入侵演练是网络安全训练的重要组成部分,旨在帮助安全人员了解攻击手法并提升防御能力。 基本组件 1. **攻击机**:通常…

手搓transformer

思路是这样子的&#xff1a;从手搓代码的角度去学习transformer&#xff0c;代码会一个一个模块地从头到尾添加&#xff0c;以便学习者跟着敲&#xff0c;到最后再手搓一个基于tansformer的机器翻译实战项目。 transformer整体架构 一、输入部分 词向量 import torch import t…

网络层协议:IP

目录 1、概念 2、关键组成部分 2.1 IP地址 2.1.1 概念 2.1.2 主要版本 2.1.3 IP地址分类 2.2 IP数据报&#xff08;IP协议传输的基本数据单元&#xff09; 3、工作原理 3.1 路由 3.2 分片与重组 4、相关协议 1、概念 目的&#xff1a;负责在复杂的网络环境中将数据…

Fastadmin报错Unknown column ‘xxx.deletetime‘ in ‘where clause

报错原因 在开启软删除后&#xff0c;设置了表别名&#xff0c;软删除字段依旧使用原表名。 解决方法 原代码 $list $this->model->with([admin, product])->where($where)->order($sort, $order)->paginate($limit);foreach ($list as $row) {$row->ge…

TCN+Transformer+SE注意力机制多分类模型 + SHAP特征重要性分析,pytorch框架

效果一览 TCNTransformerSE注意力机制多分类模型 SHAP特征重要性分析 TCN&#xff08;时序卷积网络&#xff09;的原理与应用 1. 核心机制 因果卷积&#xff1a;确保时刻 t t t 的输出仅依赖 t − 1 t-1 t−1 及之前的数据&#xff0c;避免未来信息泄露&#xff0c;严格保…

Elasticsearch的数据同步

elasticsearch中的数据多是来自数据库&#xff0c;当数据库发生改变时&#xff0c;elasticsearch也必须跟着改变&#xff0c;这个就叫做数据同步。 当我们是进行微服务的时候&#xff0c;同时两个服务不能进行相互调用的时候。就会需要进行数据同步。 方法一&#xff1a;同步…

uniapp 时钟

<template><view class"clock-view"><view class"clock-container u-m-b-66"><!-- 表盘背景 --><view class"clock-face"></view><!-- 时针 --><view class"hand hour-hand" :style&quo…

【大模型】实践之1:macOS一键部署本地大模型

Ollama + Open WebUI 自动部署脚本解析说明文档 先看下效果 一、脚本内容 #!/bin/bash set -eMODEL_NAME="qwen:1.8b" LOG_FILE="ollama_run.log" WEBUI_PORT=3000 WEBUI_CONTAINER_PORT=8080 WEBUI_URL="http://localhost:$WEBUI_PORT" DOC…

相机Camera日志实例分析之三:相机Camx【视频光斑人像录制】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…

介绍一下 TCP方式程序的通讯,服务器机与客户机

TCP通信方式&#xff1a;服务器与客户机通信详解 TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。下面我将详细介绍TCP方式下服务器与客户机的通信过程。 基本概念 TCP特点&#xff1a; 面向连接&#xff1a;通信前需建立连接可靠传输&#xff1a;…

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…

【PyTorch】2024保姆级安装教程-Python-(CPU+GPU详细完整版)-

一、准备工作 pytorch需要python3.6及以上的python版本 我是利用Anaconda来管理我的python。可自行安装Anaconda。 Anaconda官网 Free Download | Anaconda 具体Anaconda安装教程可参考 https://blog.csdn.net/weixin_43412762/article/details/129599741?fromshareblogdet…