SpringMVC 原本需要手动写 XML 配置一堆核心组件才能工作,而 SpringBoot 通过「自动配置」把这些组件全帮我们配好了,不用写任何 XML,甚至不用手动建 Bean,直接用就行;同时所有自动配置的内容都能「按需自定义」。
SpringMVC 是处理 Web 请求的核心框架,它的工作依赖一套固定的核心组件 ,就像一个工厂的「生产线」,缺一个环节都没法正常干活;而 SpringBoot 的 Web 自动配置,就是帮我们自动搭好了这条生产线,我们只需要往里面塞「业务代码」(比如写 Controller),不用自己搭生产线。
SpringBoot 专门提供了**WebMvcAutoConfiguration** (还有配套的DispatcherServletAutoConfiguration、MultipartAutoConfiguration等)这一系列自动配置类,项目只要引入了 SpringBoot 的 web 依赖 (spring-boot-starter-web),这些配置类就会自动生效,帮我们配置好 SpringMVC 的所有核心组件。
XML
<!-- 只要引入这个依赖,所有SpringMVC自动配置全部生效 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
模块1:中央转发器------DispatcherServlet
相当于Web 项目的「前台接待员」 ,所有前端发来的请求(比如http://localhost:8080/hello),第一步都会先找到它,由它来统一接收、然后分发给后面的控制器(Controller)处理,是 SpringMVC 的入口核心,没有它整个 SpringMVC 都不工作。
原生的SpringMVC配置
必须写web.xml(Web 项目的核心配置文件),手动注册这个 Servlet,指定映射路径(接管所有请求),还要设置启动时加载,否则请求进不来:
XML
<!-- 原生必须这么写 -->
<servlet>
<servlet-name>chapter2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup> <!-- 项目启动就加载,不用等第一次请求 -->
</servlet>
<servlet-mapping>
<servlet-name>chapter2</servlet-name>
<url-pattern>/</url-pattern> <!-- 接管所有请求 -->
</servlet-mapping>
SpringBoot 自动配置
- 不用写
web.xml:SpringBoot 的 Web 项目是jar 包运行 ,根本没有web.xml这个文件,底层通过代码的方式自动注册 DispatcherServlet; - 自动接管所有请求:默认把 DispatcherServlet 映射到
/,所有请求都由它处理; - 自动启动加载:默认配置为项目启动时就加载,无需等待第一次请求;
- 配置类:由
DispatcherServletAutoConfiguration这个类完成所有自动配置
SpringBoot 的默认配置完全满足 99% 的场景,几乎不需要自定义。
模块2:控制器------(业务入口)Controller
相当于工厂的 **「业务处理员」,DispatcherServlet 把请求分发给它,由它来写具体的业务逻辑(比如查数据库、处理参数、返回结果),是我们开发中写代码最多的地方 **。
原生 SpringMVC 手动配置
- 先写 Controller 类,加
@Controller注解; - 再在
spring-mvc.xml里配置组件扫描,告诉 Spring 要扫描哪个包下的 Controller,否则 Spring 识别不到:
XML
<!-- 原生必须配扫描,不然Controller白写 -->
<context:component-scan base-package="com.xxx.controller"/>
SpringBoot 自动配置
- 无需配组件扫描:只要在启动类 上加
@SpringBootApplication注解,这个注解会 ** 自动扫描「启动类所在包及所有子包」** 下的@Controller/@RestController注解类; - 直接写就行:我们只需要在指定包下写 Controller,加注解、配
@RequestMapping映射路径,就能直接接收请求,完全不用额外配置。
自定义:改扫描包(极少用)
如果 Controller 不在启动类的包下,只需在启动类加@ComponentScan指定扫描路径即可,比如:
java
@SpringBootApplication
@ComponentScan("com.xxx") // 扫描com.xxx下所有组件
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
模块3:视图解析器ViewResolver
相当于 **「页面导航员」,如果 Controller 处理完业务后要 跳转到页面 **(比如 JSP、HTML),会告诉视图解析器「我要跳转到 xxx 页面」,由视图解析器拼接完整的页面路径,找到真正的页面文件。
注:如果是前后端分离(用
@ResponseBody返回 JSON),这个组件几乎用不到。
原生 SpringMVC 手动配置
最常用的是 JSP 解析器InternalResourceViewResolver,必须在spring-mvc.xml里手动配,指定页面的前缀(prefix)和后缀(suffix),否则 Spring 找不到页面:
XML
<!-- 你的笔记里的配置,原生必须这么写 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property> <!-- 页面文件放在WEB-INF/jsp下 -->
<property name="suffix" value=".jsp"></property> <!-- 页面后缀是.jsp -->
</bean>
<!-- 比如Controller返回"index",解析器会拼接成 /WEB-INF/jsp/index.jsp -->
SpringBoot 自动配置
SpringBoot 自动配置了两个核心视图解析器,且无需手动配 Bean:
ContentNegotiatingViewResolver:它不是「直接解析页面」的解析器,而是 **「视图解析器的管理者」**------ 会整合项目中所有的视图解析器(比如你手动配的 JSP 解析器、Thymeleaf 解析器),然后根据请求的类型(比如返回页面 / 返回 JSON)选择最合适的解析器,优先级最高;BeanNameViewResolver:根据 Bean 的名字来解析视图,适合一些自定义视图的场景。
自定义:配 JSP/Thymeleaf 前缀后缀(按需)
如果你的项目用 JSP/Thymeleaf,直接在application.properties/yaml里配前缀后缀就行,不用写 XML/Bean:
# 配置JSP视图解析器
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
# 配置Thymeleaf(SpringBoot推荐,无需配后缀)
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
模块 4:文件上传 ------MultipartResolver
相当于 **「文件解析员」,专门处理前端发来的 文件上传请求 **(form 表单的enctype="multipart/form-data"),能把上传的文件解析成MultipartFile对象,让我们在 Controller 里直接操作。
原生 SpringMVC 手动配置
必须手动在spring-mvc.xml里配置CommonsMultipartResolver这个 Bean,还要引入文件上传的依赖,否则无法接收文件:
XML
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/> <!-- 最大上传10MB -->
</bean>
SpringBoot 自动配置
- 自动配置 **
StandardMultipartResolver**:无需手动配 Bean,引入spring-boot-starter-web后就生效; - 直接用
MultipartFile接收:你的笔记里的 Controller 代码就是直接用的,不用任何额外配置,SpringBoot 会自动解析上传的文件; - 默认限制:默认最大上传单个文件 10MB ,单次请求总文件 10MB(你的笔记里提到的)。
自定义:修改文件上传大小限制(重点)
直接在application.properties/yaml里配就行,这是开发中最常用的自定义配置,你的笔记里也提到了:
# 单个文件最大上传大小(比如改50MB)
spring.servlet.multipart.max-file-size=50MB
# 单次请求所有文件的总大小(比如改100MB)
spring.servlet.multipart.max-request-size=100MB
# 关闭文件上传限制(慎用)
# spring.servlet.multipart.max-file-size=-1
注:单位支持 MB/KB/B,直接写数字 + 单位即可,SpringBoot 会自动解析。
模块 5:静态资源访问 ------ 图片 / JS/CSS/HTML 等
相当于 **「静态文件管理员」,专门处理前端对 静态资源 ** 的请求(比如访问http://localhost:8080/img/1.jpg、http://localhost:8080/js/index.js),SpringMVC 默认会拦截所有请求,需要专门配置让它「放行」静态资源。
原生 SpringMVC 手动配置
必须在spring-mvc.xml里配置<mvc:resources>,指定静态资源的路径和映射,否则前端访问不到图片 / JS:
XML
<!-- 原生必须配,放行static下的所有静态资源 -->
<mvc:resources mapping="/**" location="/static/"/>
SpringBoot 自动配置
SpringBoot预设了 4 个静态资源目录 ,只要把静态文件(图片、JS、CSS、HTML)放在这些目录下,前端可以直接通过路径访问,无需任何配置:
resources/
├── static/ 【最常用】
├── public/
├── resources/
└── META-INF/resources/
示例 :把1.jpg放在resources/static/img/下,前端直接访问http://localhost:8080/img/1.jpg即可。
自定义:修改静态资源目录 / 映射路径
如果不想用默认目录,直接在配置文件里配:
# 自定义静态资源目录(多个用逗号分隔)
spring.mvc.static-path-pattern=/res/** # 前端访问前缀,比如/res/img/1.jpg
spring.web.resources.static-locations=classpath:/myStatic/,file:D:/static/ # 资源实际存放目录
模块 6:数据处理 ------ 消息转换器 + 格式化器
这两个是「数据处理搭档」,处理请求 / 响应的数类型转换 ,核心是让前后端数据交互更顺畅。
6.1 消息转换器(HttpMessageConverter)
相当于 **「前后端数据翻译官」,专门处理JSON/XML 与 Java 对象的互转 **,核心场景:
- 前端发 JSON 请求,把 JSON 字符串转成 Java 对象(比如 @RequestBody 接收参数);
- 后端返回 Java 对象,把 Java 对象转成 JSON 字符串给前端(比如 @ResponseBody 注解)。
原生 SpringMVC 手动配置
需要手动在spring-mvc.xml里配置消息转换器(比如 Jackson 的MappingJackson2HttpMessageConverter),否则无法实现 JSON 与 Java 对象互转。
SpringBoot 自动配置
自动配置了Jackson 的消息转换器 (MappingJackson2HttpMessageConverter),引入spring-boot-starter-web后就生效,我们直接用@RequestBody/@ResponseBody就行,无需任何配置 ------ 这也是为什么 SpringBoot 中加@RestController(=@Controller+@ResponseBody)能直接返回 JSON 的原因。
6.2 格式化器(Formatter)
相当于 **「基础数据转换器」,处理简单数据类型的转换 **,比如:
- 字符串转数字(前端传 "123",后端用 Integer 接收);
- 字符串转日期(前端传 "2024-01-01",后端用 Date/LocalDateTime 接收);你的笔记里重点提到了时间格式化,这是开发中最常用的场景。
原生 SpringMVC 手动配置
需要手动写格式化器类,再在spring-mvc.xml里注册,否则前端传的时间字符串无法直接转成后端的 Date 类型。
SpringBoot 自动配置
-
自动注册通用格式化器:字符串转数字、字符串转日期等,无需手动写类 / 注册;
-
时间格式化自定义(重点,你的笔记核心) :前端传的时间字符串格式不统一,直接在配置文件 里指定全局时间格式,就能自动转换,不用手动处理:
配置全局时间格式化模式(适配Date/LocalDateTime)
spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss
spring.mvc.format.time=HH:mm:ss或者用Jackson的配置(适配@ResponseBody返回的时间对象)
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
注:配完后,前端传 "2024-01-26 10:00:00",后端用 LocalDateTime 直接接收就行,SpringBoot 会自动转换。
模块 7:项目首页 ------ 欢迎页面(Welcome Page)
就是访问项目根路径 (http://localhost:8080/)时,自动跳转到的页面,比如官网的首页。
原生 SpringMVC 手动配置
需要写一个 Controller,配@RequestMapping("/"),手动返回首页路径,否则访问根路径 404。
SpringBoot 自动配置
无需写任何 Controller ,只要在静态资源目录 (就是模块 5 的 4 个目录,最常用resources/static/)下放一个名为 **index.html的文件,访问项目根路径就会自动跳转 ** 到这个页面,这是 SpringBoot 的默认规则。
自定义:改首页(极少用)
如果不想用index.html,可以手动写 Controller 映射/,返回自定义页面即可,会覆盖自动配置。
java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
// 返回模板文件名(如 templates/custom-home.html)
return "custom-home";
}
}
拓展
SpringBoot 本质是对 SSM 的 "简化封装" ,两者的核心处理逻辑完全一致 (都是 SpringMVC 的请求处理流程),区别只在配置方式、组件装配、容器管理这些 "搭架子" 的环节 ------SSM 需要手动搭架子、配零件,SpringBoot 把架子和常用零件都提前做好了,直接用就行。
SSM项目,前后端+数据库的响应流程
- 请求接入 :客户端发起的 HTTP 请求首先到达外部 Web 容器(如 Tomcat) ,Web 容器识别动态请求(非 HTML/CSS/JS 等静态资源)后,根据
web.xml的配置,将请求转发至SpringMVC 的前端控制器 DispatcherServlet(所有动态请求的统一入口)。 - 处理器映射 :DispatcherServlet 接收到请求后,通过处理器映射器 HandlerMapping ,根据请求 URL、请求方式等信息,匹配到对应的Controller 层处理方法,并将映射结果返回给 DispatcherServlet。
- 处理器适配 :DispatcherServlet 通过处理器适配器 HandlerAdapter,对目标 Controller 方法进行适配(包含参数绑定、数据类型转换、请求参数解析等操作),并调用该 Controller 方法。
- 业务层调用 :Controller 控制层 接收请求参数后,不处理具体业务逻辑,仅作为请求入口,调用标注
@Service的Service 业务层方法;Service 层作为业务核心,处理业务逻辑、事务控制、数据校验等操作。 - 数据层操作 :Service 层调用标注
@Repository的Dao 数据访问层 (MyBatis 的 Mapper 接口),通过 Spring 整合 MyBatis 的SqlSessionFactory生成的 SqlSession 代理对象,执行 Mapper 中定义的 SQL 语句,操作数据库完成数据的增删改查。 - 数据逐层返回 :数据库操作结果由 Dao 层返回至 Service 层,Service 层完成业务处理后,将结果返回至 Controller 层;Controller 层将业务结果封装至Model/ModelAndView (服务端渲染),或通过
@ResponseBody直接返回 JSON 数据(前后端分离场景)。 - 视图解析 / 数据封装 :若为服务端渲染,DispatcherServlet 接收 Controller 返回的视图名和数据后,通过视图解析器 ViewResolver 解析视图名,生成实际的物理视图路径(如 JSP/Thymeleaf 页面),并完成视图渲染 (将数据填充至视图模板);若为前后端分离,
@ResponseBody会将对象自动序列化为 JSON 字符串,直接传递给 DispatcherServlet。 - 响应返回 :DispatcherServlet 将渲染后的视图页面,或 JSON 格式的响应数据,通过外部 Web 容器返回至客户端,整个请求响应流程结束。
SpringBoot项目,前后端+数据库的响应流程
- 请求接入 :客户端 HTTP 请求到达 SpringBoot内置的嵌入式 Web 容器(默认 Tomcat,由
spring-boot-starter-web引入) ,内嵌容器识别动态请求后,直接将请求转发至自动装配的前端控制器 DispatcherServlet (由DispatcherServletAutoConfiguration自动配置,无需web.xml)。 - 处理器映射与适配 :DispatcherServlet 通过自动配置的 HandlerMapping 和 HandlerAdapter (由
WebMvcAutoConfiguration自动装配,开启注解驱动),完成请求路径与 Controller 方法的匹配、方法适配和调用,此步骤与 SSM 逻辑完全一致。 - 三层架构调用 :Controller 层 接收请求后调用Service 层 处理业务逻辑,Service 层调用Dao 层(MyBatis Mapper) 操作数据库;此三层调用逻辑、注解使用(
@Controller/@Service/@Mapper)与 SSM 完全一致,无任何变化。 - 数据库操作简化 :Dao 层通过
mybatis-spring-boot-starter完成自动化整合,SpringBoot 通过DataSourceAutoConfiguration自动配置数据源,通过 SqlSessionFactory 自动生成代理对象执行 SQL,无需手动配置 Spring 与 MyBatis 的整合 Bean,无需 XML 配置。 - 数据封装返回 :数据库操作结果逐层返回至 Controller 层,Controller 层通过
Model/ModelAndView(服务端渲染)或@RestController(=@Controller+@ResponseBody,前后端分离)封装响应数据,此步骤与 SSM 一致。 - 视图 / 数据处理 :服务端渲染场景下,由
WebMvcAutoConfiguration自动配置的ViewResolver完成视图解析和渲染;前后端分离场景下,SpringBoot 默认引入 Jackson,自动完成对象到 JSON 的序列化,无需额外配置。 - 响应返回 :DispatcherServlet 将响应数据(页面 / JSON)通过内嵌 Web 容器返回至客户端,流程结束。