Spring MVC 运行原理 【深度理解】

news2024/12/25 1:09:41

什么是MVC?

MVC 是 Model、View 和 Controller 的缩写,分别代表 Web 应用程序中的 3 种职责,MVC是一种软件设计规范。它将业务逻辑、数据、显示分离的方法来组织代码,降低了视图与业务逻辑之间的双向耦合。

  • Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层(行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
  • View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
  • Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。也就是说控制器做了个调度员的工作。

最典型的MVC模式就是JSP+Servlet+JavaBean的模式

在这里插入图片描述

什么是SpringMVC?

  • SpringMVC是一个基于MVC模式的Web框架,是Spring框架的一个模块 。
  • 它以SpringIOC容器为基础,并利用容器的特性来简化它的配置,所以 SpringMVC 和 Spring 可直接整合使用。
  • SpringMVC 对 MVC 流程进行了封装,屏蔽掉很多底层代码,让开发者可以更加轻松快捷的完成基于 MVC 模式的 Web 开发。
  • 总的来说:Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。

SpringMVC的特点:

  • 轻量级,简单易学
  • 高效 , 基于请求响应的MVC框架
  • 与Spring兼容性好,无缝结合
  • 约定优于配置
  • 功能强大:RESTful、数据验证、格式化、本地化、主题等
  • 简洁灵活

SpringMVC中的核心组件

(1)前端控制器:DispactherServlet

(2)处理器映射器:HandlerMapping

(3)处理器适配器:HandlerAdapter

(4)处理器:Handler

(5)视图解析器:ViewResolver

(6)视图:View

组件的介绍

  • 前端控制器:接收请求、响应结果,相当于转发器,它是SpringMVC框架最核心的组件,有了它就能减少其他组件之间的耦合度。(不需要程序员开发)
  • 处理器映射器:根据配置的映射规则(根据请求的URL),找到对应的处理器。(不需要程序员开发)
  • 处理器适配器:适配调用具体的处理器,并且执行处理器中处理请求的方法,执行完毕之后返回一个ModelAndView对象。
  • 处理器:(需要程序员手动开发)。
  • 视图解析器:会根据传递过来的ModelAndView对象进行视图解析,根据视图解析名解析称真正的视图View。(不需要程序员开发)
  • 视图:View是一个接口,它的实现类支持不同类型的视图。比如:JSP、freemarker、Thymeleaf等等。

SpringMVC的执行流程

在这里插入图片描述
在这里插入图片描述
(1)当用户通过浏览器发起一个HTTP请求,请求直接到前端控制器DispatcherServlet;

(2)前端控制器接收到请求以后调用处理器映射器HandlerMapping,处理器映射器根据请求的URL找到具体的Handler,并将它返回给前端控制器;

(3)前端控制器调用处理器适配器HandlerAdapter去适配调用Handler;

(4)处理器适配器会根据Handler去调用真正的处理器去处理请求,并且处理对应的业务逻辑;

(5)当处理器处理完业务之后,会返回一个ModelAndView对象给处理器适配器,HandlerAdapter再将该对象返回给前端控制器;这里的Model是返回的数据对象,View是逻辑上的View。

(6)前端控制器DispatcherServlet将返回的ModelAndView对象传给视图解析器ViewResolver进行解析,解析完成之后就会返回一个具体的视图View给前端控制器。(ViewResolver根据逻辑的View查找具体的View)

(7)前端控制器DispatcherServlet将具体的视图进行渲染,渲染完成之后响应给用户(浏览器显示)。

关于DispatcherServlet的配置说明

使用SpringMVC时,第一步就是web.xml中配置DispatcherServlet,DispatcherServlet实际上就是一个Servlet,因此我们可以配置多个DispatcherServlet,它是前端控制器,在web.xml文件中配置时,还需要配置拦截匹配的请求,以及Springmvc的配置文件的加载,还有启动顺序的配置,使得该servlet随着Servlet容器的启动而启动,以下就是关于DispatcherServlet的常规配置:

<!--配置前端控制器-->
    <servlet>
        <servlet-name>DispactherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!--配置加载Springmvc的配置文件-->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-config.xml</param-value>
        </init-param>
        <!--配置启动顺序,数字越小启动优先级越高-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispactherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

以上指明了配置文件的文件名,不使用默认配置文件名,而使用springmvc-config.xml配置文件。
其中**.xml 这里可以使用多种写法
1、不写,使用默认值:/WEB-INF/-servlet.xml
2、/WEB-INF/classes/springMVC.xml
3、classpath*:springmvc-config.xml
4、多个值用逗号分隔

关于SpringMVC的配置文件以及常用部分注解解释

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--自动扫描指定的包,下面所有注解类交给IOC容器处理-->
    <context:component-scan base-package="com.oldou.controller"/>

    <!--配置注解驱动-->
    <mvc:annotation-driven/>

    <!--配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    
     <!--配置对静态资源的访问(方式一) 21-->
	 <mvc:default-servlet-handler/>  	
	<!--配置对静态资源的访问(方式二) 21-->
	<mvc:resources mapping="/js/**" location="/WEB-INF/js/"/>
    <mvc:resources mapping="/img/**" location="/WEB-INF/img/"/>
    <mvc:resources mapping="/css/**" location="/WEB-INF/css/"/>
	
    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** 包括路径及其子路径-->
            <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
            <!--/admin/** 拦截的是/admin/下的所有-->
            <mvc:mapping path="/**"/>
            <!--bean配置的就是拦截器-->
            <bean class="com.oldou.Interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

<!--文件上传配置-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
   <property name="defaultEncoding" value="utf-8"/>
   <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
   <property name="maxUploadSize" value="10485760"/>
   <property name="maxInMemorySize" value="40960"/>
</bean>

</beans>

以上配置中,配置了扫描Controller层的注解扫描以及注解的驱动支持,还有视图解析器、静态资源映射器、拦截器等等,里面还可以配置文件的上传等等。

Spring MVC常用的注解

  • @Controller 声明Controller组件,通常作用在控制层(如 Spring MVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Service 声明Service组件 @Service(“myMovieLister”) ,通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Repository 声明Dao组件,将数据访问层(DAO 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Component 泛指组件, 可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
  • @RequestMapping(“/menu”) 请求映射,用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
  • @Resource 用于注入,( j2ee提供的 ) 默认按名称装配
  • @Autowired 用于注入,(srping提供的) 默认按类型装配
  • @Transactional( rollbackFor={Exception.class}) 事务管理
  • @RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
  • @ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。
  • @Scope(“prototype”) 设定bean的作用域
  • @GetMapping:它是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式,只能处理 Get 类型请求。
  • @PostMapping: 它是@RequestMapping(method =RequestMethod.POST) 的一个快捷方式,只能处理 Post 类型请求。
  • @RequestParam :将请求参数绑定到控制器的方法参数上
  • @Configuration:声明当前类为配置类,相当于 xml 形式的 Spring 配置中的,该注解需要添加到类上。
  • @Resource(name=“beanName”)

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

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

相关文章

newMap和newSet

newMap Map 对象存有键值对&#xff0c;其中的键可以是任何数据类型。Map字典是以[键&#xff0c;值]的形式存储** 1:键值对的键类型比较灵活 可以用任意类型的变量来做键名&#xff0c; 2 遍历键值对 for … in循环还有一些限制&#xff1a;它仅仅遍历可枚举属性、非Symb…

进程概念与进程控制

1.冯诺伊曼体系结构: 数据按照二进制存储 数据存储在存储器&#xff08;内存&#xff09;当中 输入设备 存储器 中央处理器 输出设备 2.操作系统&#xff1a; 先组织&#xff0c;再描述 系统调用与库函数&#xff1a; 系统调用 系统调用指运行在用户空间的程序向操作系统内核…

小程序-----vant weapp安装以及自定义主题色

首先查看小程序根目录中是否存在package.json文件 没有的话,在项目根目录打开cmd,输入npm init -y初始化一下,初始化一个包管理 安装vant weapp包 在根目录的cmd中输入npm i vant/weapp1.3.3 -S --production进行安装 后面可以指定版本 修改 app.json 将 app.json 中的 “…

【Python】类型注解 ③ ( 使用 # type: 类型 注释方式设置类型注解 | 类型注解是提示性而非强制性 )

文章目录 一、使用 注释语法 设置 类型注解1、使用 注释语法 设置 类型注解语法介绍2、为 基础类型变量 设置 " 类型注解 "3、为 类 的 对象类型 设置 " 类型注解 "4、为 基础容器类型变量 设置 简易 " 类型注解 "5、为 基础容器类型变量 设置 详…

Node.js下载安装和环境变量配置(详细教程)

目录 一、官网地址下载安装包 二、安装程序 三、环境配置 四、测试 五、安装淘宝镜像 5.1、附加&#xff1a;如果有出现问题的小伙伴们可以检查一下自己的配置有没有出错 一、官网地址下载安装包 https://nodejs.org/zh-cn/download/ 选择你的项目或系统对应的node.js版本…

【C++】 Qt-线程并发与线程同步

文章目录 线程并发线程同步原子访问&#xff08;InterLocked&#xff09;关键段&#xff08;Critical_Section&#xff0c;也叫临界区&#xff09;回顾单例出现的问题关键段基本使用封装关键段 Qt下的多线程多线程与进度条Qt-QThread 线程并发 我们再创建一个控制台文件命名为…

【Tauri + React 实战】VCluster - 了解技术选型与开发环境配置

VCluster A React Tauri App as visualizer of apps cluster on windows. 背景介绍 VCluster是一个在开发环境下&#xff0c;用以对一系列应用集群&#xff08;如分布式、微服务&#xff09;进行可视化管理的桌面应用程序&#xff0c;目标是实现类似 docker-compose 那样的集…

深入学习Python自定义函数

目录 0. 前言1. 最基础的自定义函数写法2. 参数传递3. 函数返回值4. 作用域5. 匿名函数6. 装饰器7. 闭包8. 生成器9. 为自定义函数写注解 0. 前言 今天来深入学习 Python 中的自定义函数&#xff0c;为的是日后能够写出时间和内存更好的优化&#xff0c;以及形成良好的编程习惯…

原型链:揭开JavaScript背后的神秘面纱

文章目录 1. 对象2. 原型&#xff08;prototype&#xff09;3. 原型链&#xff08;prototype chain&#xff09;4. 构造函数&#xff08;constructor&#xff09;5. prototype 属性6. 实例&#xff08;instance&#xff09;7. 原型继承&#xff08;prototype inheritance&#…

HFSS仿真微带型威尔金森功分器学习笔记

HFSS仿真微带型威尔金森功分器 文章目录 HFSS仿真微带型威尔金森功分器1、 求解器设置2、 建模3、 边界条件设置4、 激励方式设置5、 扫频设置6、 设计检查&#xff0c;仿真分析7、 数据后处理 设计要求&#xff1a; 频带范围0.9~1.1GHz输入端口的回波损耗&#xff1e;20dB频带…

STL算法篇之拷贝修改类算法

STL算法篇之拷贝修改类算法 拷贝类算法copy与copy_backwardremove与remove_copyremove_if与remove_copy_if 修改类算法replace与replace_copyreplace_if与replace_copy_ifiter_swap与swap与swap_range、unique与unique_copy 拷贝类算法 1.copy 区间拷贝 2.copy_backward 逆向拷…

Redis双写一致性?

双写一致性&#xff1a;当修改了数据库的数据也要同时更新缓存的数据&#xff0c;缓存和数据库的数据要保持一致。 Redis作为缓存&#xff0c;mysql的数据如何与redis进行同步呢&#xff1f;&#xff08;双写一致性&#xff09; 1.我们当时做排行榜业务时&#xff0c;把历史榜…

CentOS7中安装docker并配置阿里云加速器

文章目录 一、docker的安装二、docker的卸载三、配置加速器四、docker-compose安装五、docker-compose卸载六、docker-compose相关命令七、常用shell组合 一、docker的安装 参考&#xff1a;https://docs.docker.com/engine/install/centos 本文内容是基于&#xff1a;CentOS L…

Python 算法基础篇:大O符号表示法和常见时间复杂度分析

Python 算法基础篇&#xff1a;大 O 符号表示法和常见时间复杂度分析 引言 1. 大 O 符号表示法 a ) 大 O 符号的定义 b ) 示例代码 2. 常见时间复杂度分析总结 引言 在分析和比较算法的性能时&#xff0c;时间复杂度是一项重要的指标。而大 O 符号表示法是用来描述算法时间复杂…

Redis 从入门到精通【进阶篇】之Lua脚本详解

文章目录 0. 前言1. Redis Lua脚本简介1.1 Lua脚本介绍Lua语言概述&#xff1a;Lua脚本的特点&#xff1a; 1.2 Redis中为何选择LuaLua与Redis的结合优势Lua脚本在Redis中的应用场景 2. Redis Lua脚本的执行流程1. 加载脚本&#xff1a;1.1 脚本缓存机制&#xff1a;1.2 脚本加…

C++ 可变参数函数用法与template模板泛型编程

目录 1、可变参数函数 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;常用使用场景 2、template模板用法 1、可变参数函数 &#xff08;1&#xff09;定义 可变参数函数的可变参数一般使用省略号表示&#xff0c;如下&#xff1a; void func(int a,...);{} &…

牛P!安卓渗透神器PhoneSploit-Pro

工具介绍 一种集成的黑客工具&#xff0c;可使用ADB(Android Debug Bridge) 和Metasploit-Framework完成自动化&#xff0c;一键获取 Meterpreter 会话。 关注【Hack分享吧】公众号&#xff0c;回复关键字【230524】获取下载链接 如果设备打开了 ADB 端口&#xff0c;该工具可…

关于Context和ContextImpl还有ContextWrapper的关系

关于Context和ContextImpl还有ContextWrapper的关系 1.Context和ContextImpl还有ContextWrapper的关系 ​ 图一.Context和ContextImpl还有ContextWrapper的关系示意图 1.1.ContextImpl是Context的实现类 从Context和ContextImpl的源代码中,可以看出Context是一个抽象类,具体…

pytorch+CRNN实现

最近接触了一个仪表盘识别的项目&#xff0c;简单调研以后发现可以用CRNN来做。但是手边缺少仪表盘数据集&#xff0c;就先用ICDAR2013试了一下。 结果遇到了一系列坑。为了不使读者和自己在以后的日子继续遭罪。我把正确的代码发到下面了。 1&#xff09;超参数请不要调整&am…

实体店搭建多用户商城系统有什么好处

现在很多的线下店铺都开始慢慢的转型线上了&#xff0c;想线上线下相结合&#xff0c;但是最近很多的商家都在问什么样的B2B2C商城系统开发适合线下店铺呢?这个问题今天加速度jsudo小编给大家一起整理如下&#xff0c;相信商家看完后就知道如何选择一款合适的商城系统了。 一、…