Spring Boot Web开发与内嵌容器详解

Spring Boot Web开发与内嵌容器详解

定位:第 05 篇,讲透内嵌容器机制与定制、Web 相关自动配置、静态资源、错误处理与常见 Web 定制

适用版本:Spring Boot 3.x(JDK 17+)


目录


一、内嵌容器

1.1 机制

spring-boot-starter-web 默认引入内嵌 Tomcat 。Boot 的 ServletWebServerFactoryAutoConfiguration 在容器刷新的 onRefresh 阶段(FW-01 refresh 第⑨步)创建并启动内嵌 Servlet 容器,注册 DispatcherServlet。

复制代码
refresh → onRefresh
   → createWebServer():创建 Tomcat 实例、配置连接器
   → 注册 DispatcherServlet、过滤器
   → 启动监听

1.2 切换容器

复制代码
默认:Tomcat
换 Undertow:排除 spring-boot-starter-tomcat,引入 spring-boot-starter-undertow
换 Jetty:同理换 jetty
响应式(WebFlux):默认 Netty

1.3 定制容器的三种方式

复制代码
① 属性:server.port / server.servlet.context-path / server.tomcat.threads.max
② WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>(编程式)
③ 直接自定义 Servlet/Filter/Listener 注册(ServletRegistrationBean 等)

二、Web 自动配置

WebMvcAutoConfiguration(WB 篇细讲机制)默认提供:

装配 说明
DispatcherServlet 前端控制器,映射 /
消息转换器 Jackson(JSON)、String、表单等
静态资源处理 映射 classpath 资源到 /**
欢迎页/错误页 默认行为
格式化 日期、数字格式化支持

定制而不覆盖 :想加拦截器/改格式化,实现 WebMvcConfigurer(加配置),而不是 @EnableWebMvc(后者关闭 Boot 默认自动配置,全部手写------除非确有必要不要用)。


三、静态资源与模板

3.1 静态资源

默认从这些位置服务静态文件,映射到 /**:

复制代码
classpath:/static/、classpath:/public/、classpath:/resources/、classpath:/META-INF/resources/

src/main/resources/static/app.js  →  http://host/app.js

3.2 模板引擎

引入对应 starter(如 Thymeleaf),模板放 classpath:/templates/,由自动配置装配视图解析:

复制代码
@GetMapping("/page")
String page(Model m) { m.addAttribute("name", "x"); return "index"; }
   → 渲染 templates/index.html

前后端分离项目通常不用模板引擎,纯 REST + 前端工程。


四、错误处理

4.1 默认机制

未捕获异常/404 默认转发到 /error,返回状态码 + 默认错误体(HTML 或 JSON)。

4.2 全局异常处理(主流做法)

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BizException.class)
    public ResponseEntity<ErrorBody> biz(BizException e) {
        return ResponseEntity.badRequest().body(new ErrorBody(e.getCode(), e.getMessage()));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorBody> fallback(Exception e) {
        return ResponseEntity.status(500).body(ErrorBody.internal());
    }
}

此处强调:生产必须有全局兜底,避免堆栈直接暴露。

4.3 自定义错误页/控制器

静态错误页放 src/main/resources/error/404.html;深度定制实现 ErrorController。


五、常见定制

5.1 JSON 定制

复制代码
# 属性方式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.property-naming-strategy=SNAKE_CASE

# Bean 方式(更灵活):自定义 ObjectMapper 或 Jackson2ObjectMapperBuilderCustomizer

5.2 文件上传大小

复制代码
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=20MB

5.3 优雅停机

复制代码
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

停机时停止接收新请求、等待在途请求完成(超时强制关闭)------发布零中断的关键(呼应无损上下线)。

5.4 CORS

java 复制代码
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry r) {
        r.addMapping("/api/**").allowedOrigins("https://web.example.com");
    }
}

六、总结

  1. 内嵌容器:starter-web 默认 Tomcat,在 refresh 的 onRefresh 阶段创建启动;可换 Undertow/Jetty;定制走属性或 WebServerFactoryCustomizer。
  2. Web 自动配置:DispatcherServlet、消息转换、静态资源、默认 MVC 行为;用 WebMvcConfigurer 增量定制,勿用 @EnableWebMvc 覆盖默认。
  3. 静态/模板:静态资源默认映射若干 classpath 目录;模板引擎走 starter + templates/。
  4. 错误处理:默认 /error;生产用 @RestControllerAdvice 全局兜底,避免堆栈外泄。
  5. 高频定制:Jackson、multipart 大小、优雅停机(server.shutdown=graceful)、CORS。

七、常见高频面试题

1. Spring Boot 如何启动内嵌 Tomcat?

要点:starter-web 引入内嵌 Tomcat 依赖;应用启动刷新上下文时,ServletWebServerFactoryAutoConfiguration 在 onRefresh 阶段(refresh 第⑨步)通过 ServletWebServerFactory 创建 Tomcat 实例、配置连接器,注册 DispatcherServlet 与过滤器,然后启动监听端口。这改变了"应用部署进外部容器"的传统模型,变为容器随应用走,java -jar 直接运行。

2. 怎么切换内嵌容器(如换成 Undertow)?

要点:排除默认的 Tomcat 依赖再引入目标容器。Maven 中在 spring-boot-starter-web 里 exclude spring-boot-starter-tomcat,然后引入 spring-boot-starter-undertow(或 jetty)。Boot 的自动配置按 classpath 上存在的容器选择对应工厂。响应式应用(WebFlux)默认用 Netty。切换主要为了性能特性或团队偏好,功能上通常无差异。

3. @EnableWebMvc 和 WebMvcConfigurer 的区别?Boot 里用哪个?

要点:@EnableWebMvc 会完全接管 MVC 配置,关闭 Spring Boot 的 WebMvcAutoConfiguration 默认行为(静态资源、默认转换器、格式化等都没了),需要全部手写,除非要完全控制否则不要用。WebMvcConfigurer 是增量定制接口------实现它的方法(加拦截器、改 CORS、配格式化)叠加在 Boot 默认配置之上,保留默认便利。Boot 项目标准做法是实现 WebMvcConfigurer。

4. Spring Boot 默认如何处理静态资源?

要点:自动配置把 classpath 下的 /static/、/public/、/resources/、/META-INF/resources/ 目录映射到 /** 路径对外服务,如 static/app.js 可通过 /app.js 访问。可通过属性自定义位置与映射(spring.web.resources)。对前后端分离项目,静态资源常由前端服务器/CDN 托管,Boot 只提供 API。

5. Spring Boot 如何做全局异常处理?

要点:主流是 @RestControllerAdvice(@ControllerAdvice + @ResponseBody)定义全局异常处理器,用 @ExceptionHandler 按异常类型映射为统一错误响应(状态码 + 错误体),覆盖业务异常、参数校验异常、兜底 Exception。它替代默认的 /error 白页,避免堆栈信息外泄,统一错误格式供前端处理。也可配静态错误页或自定义 ErrorController。

6. 如何定制 Jackson 的 JSON 序列化(如日期格式)?

要点:简单场景用属性:spring.jackson.date-format、property-naming-strategy 等。复杂场景定义 Bean:自定义 ObjectMapper 覆盖默认,或更推荐实现 Jackson2ObjectMapperBuilderCustomizer(在默认基础上增量定制,保留 Boot 默认模块)。注意直接 new ObjectMapper 作 Bean 会丢失 Boot 的默认配置,应谨慎。

7. 什么是优雅停机?怎么开启?

要点:优雅停机在关闭时先停止接收新请求,等待在途请求处理完(有超时上限)再关闭,避免发布期间用户请求被硬断。开启:server.shutdown=graceful,配合 spring.lifecycle.timeout-per-shutdown-phase 设等待上限。配合负载均衡摘流与容器编排的停机钩子,实现发布零中断。

8. 文件上传大小限制怎么配?

要点:默认上限较小(单文件与总请求各有限制),需显式调大:spring.servlet.multipart.max-file-size(单文件)、spring.servlet.multipart.max-request-size(整请求)。同时注意反向代理(Nginx client_max_body_size)与内嵌容器层的限制,任一层卡住都会失败。大文件建议对象存储直传而非经应用转发。

9. WebMvcAutoConfiguration 都自动装配了什么?

要点:主要包括------DispatcherServlet(映射 /)、HttpMessageConverter(Jackson JSON、String、表单等)、静态资源处理与欢迎页、默认错误处理基础、日期/数字格式化支持、表单编码等。这些构成"零配置即可用的 Web 层"。理解它有助于解释为什么引入 starter-web 就能直接写 @RestController 返回 JSON。

10. 为什么生产要配置全局异常兜底?

要点:没有兜底时未捕获异常走默认 /error,可能暴露堆栈与内部信息(安全风险),且错误格式不统一让前端无法可靠处理。全局 @RestControllerAdvice 统一捕获并转换为约定的错误响应(状态码 + 错误码 + 消息),区分业务异常与系统异常,系统异常记日志告警但不回传细节。这是接口规范与安全的基本要求。

相关推荐
Q26433650232 小时前
【有源码】基于Spring Boot和Vue的在线考试与交流系统-教育信息化背景下在线考试与交流一体化平台
java·vue.js·spring boot·mysql·spring·毕业设计·课程设计
EatFan2 小时前
2026 后端 AI 集成三条落地路径:Spring AI 2.0、MCP 协议与旁路服务怎么选
java·人工智能·spring boot·spring·大模型·spring ai·mcp
imDwAaY3 小时前
Spring Boot的核心配置文件一览及其加载顺序
java·spring boot·后端
专业程序开发源4 小时前
springboot校园志愿者管理系统28562-计算机课程设计、毕业设计
java·spring boot·后端·python·django·php·课程设计
vx-程序开发1 天前
【计算机毕设】51300童装超市管理系统的设计与实现
java·vue.js·spring boot·源码·课程设计·毕设·大作业
ym hyd 1111 天前
题库建立与考试系统源码 Java+SpringBoot+Vue3 前后分离
java·开发语言·vue.js·spring boot·毕设
萧瑟余晖1 天前
Spring Boot Starter机制与自定义详解
spring boot
vx-程序开发1 天前
【计算机毕设】52744基于微信小程序的民宿智能预订系统
java·spring boot·毕业设计·源码·课程设计·毕设·大作业
萧瑟余晖1 天前
Spring Boot 配置体系详解
spring boot