SpringMVC 执行流程分析 详解(图解SpringMVC执行流程)

目录

一、拾枝杂谈

1.MVC的定义:

2.SpringMVC概述:

3.SpringMVC特点:

4.SpringMVC,Spring,和SpringBoot的关系:

[二、SpringMVC 快速入门](#二、SpringMVC 快速入门)

1.引入依赖:

2.配置中央控制器和视图解析器:

3.搭建简单的前后端业务:

4.运行测试:

三、SpringMVC执行流程分析

[1.浏览器使用 URL 发出 HTTP请求:](#1.浏览器使用 URL 发出 HTTP请求:)

[2.前端控制器 调用 处理器映射器:](#2.前端控制器 调用 处理器映射器:)

[3.处理器映射器返回 处理器执行链:](#3.处理器映射器返回 处理器执行链:)

4.前端控制器继续调用处理器适配器:

[5.处理器适配器 调用 Handler:](#5.处理器适配器 调用 Handler:)

[6.Handler 返回数据给 处理器适配器:](#6.Handler 返回数据给 处理器适配器:)

[7.处理器适配器 继续将数据返回给 前端控制器:](#7.处理器适配器 继续将数据返回给 前端控制器:)

[8.前端控制器 调用 视图解析器:](#8.前端控制器 调用 视图解析器:)

[9.视图解析器 将解析后的结果返回给 前端控制器:](#9.视图解析器 将解析后的结果返回给 前端控制器:)

[10.通过具体的 视图技术(View)进行视图渲染:](#10.通过具体的 视图技术(View)进行视图渲染:)

[11.前端控制器 返回 HTTP响应 给浏览器:](#11.前端控制器 返回 HTTP响应 给浏览器:)

[Δ总览 / 总结 SpringMVC的执行流程(一张全景图):](#Δ总览 / 总结 SpringMVC的执行流程(一张全景图):)

Δ总结


一、拾枝杂谈

1.MVC的定义:

(1) MVC,分别是指Model(模型),View(视图),Controller(控制器)------
++Model++ : 将与业务逻辑相关的数据封装 为具体的 JavaBean类(JavaBean/Domain/POJO),其中不掺杂任何与数据处理相关的代码。
++View++ : 只负责数据和界面的显示,不接受任何与显示 数据无关的代码,便于程序员和美工的分工合作。(Vue/Jsp/Thymeleaf/HTML)。
++Controller++ : 只负责接收请求,调用Service层的代码处理请求,然后派发页面,起到"调度者 "的作用。

(2) MVC最早出现于 JavaEE三层架构 中的 Web层 ,可以指导Web层的代码实现有效分离,单独工作,其本质就是将软件代码拆分成为组件单独开发,组合使用,达到了解耦 的目的。MVC是一种思想,体现的是 数据显示数据处理业务调用的分离解耦。SpringMVC就是一种基于MVC思想的 WEB层框架。

(3) JavaEE三次架构如下图所示

(4) MVC 是设计模式 ,聚焦于表现层(Web 层)的职责分离(Model-View-Controller)。Service 层和 DAO 层是分层架构,属于业务逻辑层和数据访问层,与 MVC 中的 "Model" 对应。

MVC思想在web层的应用如下图所示:

2.SpringMVC概述:

(1) SpringMVC 是基于 Spring 的web层框架 ,即SpringMVC 接管了 WEB层组件(例如控制器,视图,视图解析等)。

(2) SpringMVC 的核心jar包是 spring-webmvc-xx.jarspring-web.xx.jar, 在 Spring 的libs目录下可以找到。如下图所示:

3.SpringMVC特点:

(1) SpringMVC 支持 REST格式的 URL 请求。

(2) SpringMVC 采用 低耦合的组件设计方式,具有更好的扩展性和灵活性。

(3) SpringMVC 通过 注解即可让POJO成为Controller,而不必像原生WEB开发一样去继承一个类(如HttpServlet)或者去实现接口。

4.SpringMVC,Spring,和SpringBoot的关系:

(1) SpringMVC 只是 Spring 中负责处理 WEB层 请求的 一个模块/组件,SpringMVC的底层是Servlet(传统的JavaWeb开发)。

(2) SpringBoot 是为了帮助开发者简化Java开发,而推出的牛逼框架(约定优于配置),简化了Spring的配置流程,SpringBoot中包含有很多Spring的组件,可以说Spring就是其最核心的内容之一,当然也就包含了SpringMVC。


二、SpringMVC 快速入门

1.引入依赖:

创建一个新的 Java 项目,并引入 Web Application 支持,如下图所示:

然后在 WEB-INF/lib 目录下,导入所有需要的 jar 包,如下图所示:

2.配置中央控制器和视图解析器:

下一步在 web.xml 中配置一个 中央控制器(也叫前端控制器),用于处理所有的应用请求(后面会讲到中央控制器)。web.xml 配置如下:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!-- 配置中央控制器 -->
    <servlet>
        <servlet-name>mvcDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!-- 通过 contextConfigLocation 指定 DispatcherServlet -->
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvcDispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
        <!--
            url-pattern == /, 表示所有的用户请求都会经过 DispatcherServlet, 且支持Rest风格。
        -->
    </servlet-mapping>
</web-app>

如果不在 web.xml 指定 applicationContext-mvc.xml, 默认在**/WEB-INF/springDispatcherServlet-servlet.xml** 找这个配置文件。

除了在 web.xml 中配置 中央控制器(DispatcherServlet),现在还需要配置 视图解析器 ,视图解析器被配置在 Spring 的xml配置文件中,为了特意标识 SpringMVC,up将其命名为applicationContext-mvc.xml代码如下:

XML 复制代码
<?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 https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置要扫描的包 -->
    <context:component-scan base-package="com.cyan.web"/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--
            视图解析器需要配置两个属性------prefix(前缀) 和 suffix(后缀),
            视图解析器收到Servlet的 "return "login_OK";" 时,会用prefix和suffix与返回的资源名拼接。
        -->
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!-- 激活注解(开启 Spring MVC 注解驱动) -->
    <mvc:annotation-driven/>
</beans>

3.搭建简单的前后端业务:

为了演示SpringMVC 对Web层的接管,我们需要先创建一个简单的 登陆页面 ,然后通过登录页面的 表单 发起请求,并在后端的 Servlet 中进行请求的处理和返回。login.jsp 代码如下

html 复制代码
<%--
    User : Cyan_RA9
    Version : 21.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Sign In</title>
</head>
<body>
    <h2 style="alignment: center">Sign In Page</h2>
    <%-- 回顾:这里的action前面为什么不能带/ --%>
    <%--  更稳健的写法------<form action="${pageContext.request.contextPath}/login">  --%>
    <form action="login">
        <table border="1" cellspacing="0" cellpadding="10">
            <tr>
                <th colspan="2">Sign In</th>
            </tr>
            <tr>
                <td>username: </td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>password: </td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td><input type="submit" value="submit"/></td>
                <td><input type="reset" value="reset"/></td>
            </tr>
        </table>
    </form>
</body>
</html>

login.jsp 页面效果图如下:(需要配置好 Tomcat)

后端用于处理 "用户登录" 请求的 UserServlet 代码如下:

java 复制代码
package com.cyan.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author : Cyan_RA9
 * @version : 22.0
 */

@Controller //@Controller注解,标识当前类是一个控制器,有时也称为Handler(处理器)
public class UserServlet {
    /*
        1. @RequestMapping 的 value 表示该方法的url映射,即当用户在浏览器地址栏输入
            http://localhost:8080/web工程路径/login 时,就可以访问到login()方法。
        2. return "login_OK",表示返回结果给视图解析器(InternalResourceViewResolver)
            ,视图解析器会根据配置,来决定跳转到哪个页面。
     */
    @RequestMapping(value = "/login")   //此处的value可以省略
    public String login() {
        System.out.println("Successfully log in");
        return "login_OK";
    }
}

由 UserServlet 的代码可以看出,还需要再来一个 login_OK.jsp 页面,代码如下:

html 复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login_OK</title>
</head>
<body>
    <h1>Sign In Successfully!</h1>
</body>
</html>

login_OK.jsp 页面效果图如下:(需要配置好 Tomcat)

此时的 WEB 工程目录结构,如下图所示:

4.运行测试:

测试结果如下GIF图所示:


三、SpringMVC执行流程分析

1.浏览器使用 URL 发出 HTTP请求:

浏览器解析URL后,向服务器发出HTTP请求,如下图所示:

2.前端控制器 调用 处理器映射器:

服务器端的 前端控制器 进一步去调用 处理器映射器,如下图所示:

3.处理器映射器返回 处理器执行链:

处理器映射器 会返回 处理器执行链,具体包括多个 拦截器 和要调用的 处理器,如下图所示:

4.前端控制器继续调用处理器适配器:

服务器端的 前端控制器 为了获得需要的Handler,再去调用处理器适配器(需要处理器适配器的帮助),如下图所示:

5.处理器适配器 调用 Handler:

处理器适配器 才是真正去调用 Handler 的那个东西,而 Handler 会执行我们自己的业务逻辑,即Service,DAO那一套。如下图所示:

6.Handler 返回数据给 处理器适配器:

处理器执行完毕业务逻辑后,会返回 ModelAndView,包括了用户数据 和 指定的要转发的View。如下图所示:

7.处理器适配器 继续将数据返回给 前端控制器:

处理器适配器 收到 Handler 发回的数据后,并不会进行对应的处理,而是会将数据继续返回给最开始的 前端控制器。如下图所示:

8.前端控制器 调用 视图解析器:

前端控制器 收到 处理器适配器 返回的ModelAndView之后,会调用配置好的 视图解析器 来查找并渲染最终的视图,也就是我们在 Spring 的配置文件中配置的 InternalResourceViewResolver。如下图所示:

9.视图解析器 将解析后的结果返回给 前端控制器:

视图解析器 收到 前端控制器 传来的逻辑视图名后,会根据自身配置的规则(例如前缀、后缀、视图技术类型),将逻辑视图名解析成一个具体的视图实现(例如 JstlView、ThymeleafView 等)以及其物理位置(例如 /WEB-INF/views/userList.jsp),并最终返回给 前端控制器。如下图所示:

10.通过具体的 视图技术(View)进行视图渲染:

前端控制器 命令 视图解析器 去协调具体的视图技术 对视图进行渲染。具体视图(View)是真正执行渲染操作的组件。它封装了特定的视图技术(如 JSP、Thymeleaf、FreeMarker 等)的渲染逻辑。如下图所示:

11.前端控制器 返回 HTTP响应 给浏览器:

在拿到最终渲染后的视图后,前端控制器会将结果打包成HTTP响应并返回给浏览器,如下图所示:

Δ总览 / 总结 SpringMVC的执行流程(一张全景图):

将之前的所有步骤合并为一张图,如下所示:


Δ总结

  • 🆗,以上就是文章的全部内容了😀。
  • 这算是 SpringMVC 的一篇入门文章,一开始做了一个入门案例。文章主体还是后面的 "图解SpringMVC执行流程"部分。大家也可以跟着up一起画一画。
相关推荐
索迪迈科技2 小时前
Java-Spring入门指南(四)深入IOC本质与依赖注入(DI)实战
java·开发语言·spring
工藤学编程2 小时前
零基础学AI大模型之读懂AI大模型
人工智能
h_k100863 小时前
如何使用 DeepSeek 帮助自己的工作?的技术文章大纲
人工智能
minhuan3 小时前
构建AI智能体:二十八、大语言模型BERT:原理、应用结合日常场景实践全面解析
人工智能·语言模型·自然语言处理·bert·ai大模型·rag
练习时长一年3 小时前
自定义事件发布器
java·前端·数据库
nightunderblackcat3 小时前
新手向:实现验证码程序
java·spring boot·spring·java-ee·kafka·maven·intellij-idea
oioihoii3 小时前
构造函数和析构函数中的多态陷阱:C++的隐秘角落
java·开发语言·c++
xrkhy4 小时前
SpringBoot之缓存(最详细)
spring boot·后端·缓存
IT_陈寒4 小时前
SpringBoot高并发优化:这5个被忽视的配置让你的QPS提升300%
前端·人工智能·后端