学习24
回答问题先回答是什么,特点(优缺点),应用场景
81. 什么是 Spring MVC?它的核心设计理念是什么?
Spring MVC 是 Spring 框架中用于构建 Web 应用程序的模块,它基于 Java 实现了 MVC(模型-视图-控制器)设计模式,是一个请求驱动的轻量级 Web 框架。
核心设计理念
它的核心设计理念围绕 “解耦” 与 “可扩展” 展开,主要体现在以下几个方面:
- 职责分离与松耦合:严格遵循 MVC 模式,将业务逻辑(Controller)、数据(Model)与界面展示(View)分离。控制器不直接依赖具体的视图技术(如 JSP),而是返回一个逻辑视图名,由
ViewResolver负责解析,从而让控制器和视图可以独立演进。 - 基于前端控制器(Front Controller)模式:核心组件
DispatcherServlet作为统一入口,接收所有请求,并将具体工作委托给可配置的策略组件(如HandlerMapping负责路由、ViewResolver负责视图解析)。这种设计将流程控制与具体实现解耦,使得各个组件可以通过接口灵活替换或扩展。 - 与 Spring IoC 容器深度集成:Spring MVC 完全融入 Spring 的依赖注入体系,控制器等组件作为普通的 Bean 由容器管理。这使得开发者可以透明地使用 Spring 的其他功能(如 AOP、事务管理),同时便于进行单元测试。
- 面向接口与高度可配置:框架的各个核心环节(如
HandlerMapping、HandlerAdapter、ViewResolver)均定义为接口。开发者可以根据需求选择或自定义实现,这赋予了框架极大的灵活性,能够适配不同的视图技术(JSP、FreeMarker、Thymeleaf 等)和开发风格。
82. 描述 Spring MVC 的请求处理流程(工作原理)
Spring MVC 的请求处理流程以 DispatcherServlet 为核心,采用前端控制器模式,将请求处理职责分派给多个可配置的策略组件。整体流程如下:
请求处理流程
- 请求到达 DispatcherServlet
用户发起 HTTP 请求,首先到达 Web 容器(如 Tomcat),容器根据web.xml或 Java 配置将匹配的请求统一交给DispatcherServlet处理。DispatcherServlet是整个流程的调度中心。 - 查找处理器(HandlerMapping)
DispatcherServlet调用HandlerMapping组件,根据请求的 URL、HTTP 方法等信息,查找对应的处理器(通常是一个@Controller类中的方法)以及与之关联的拦截器(Interceptor),并将结果封装为HandlerExecutionChain返回。 - 获取处理器适配器(HandlerAdapter)
由于处理器有多种实现方式(注解式、实现Controller接口等),DispatcherServlet通过HandlerAdapter来统一调用处理器。它会遍历已注册的HandlerAdapter,找到支持当前处理器的适配器。 - 执行拦截器前置方法
在真正调用处理器之前,DispatcherServlet会依次执行HandlerExecutionChain中拦截器的preHandle方法。若某个拦截器返回false,则中断后续流程。 - 调用处理器(Controller)
HandlerAdapter调用处理器方法。在此过程中,HandlerAdapter负责完成参数绑定(如将请求参数、路径变量、请求体等解析并绑定到方法参数上),然后执行控制器中的业务逻辑。处理器执行完毕后返回一个ModelAndView(或视图名、ResponseEntity等)。 - 处理返回结果
如果处理器返回的是ModelAndView,DispatcherServlet会交给ViewResolver将逻辑视图名解析为具体的View对象。若方法使用了@ResponseBody或返回ResponseEntity,则由HttpMessageConverter直接将返回值序列化为响应体(如 JSON),跳过视图解析环节。 - 渲染视图
对于需要渲染视图的情况,DispatcherServlet将Model中的数据传递给View对象,由View完成渲染(如生成 HTML)。 - 执行拦截器后置方法
在视图渲染前后,会依次执行拦截器的postHandle方法(视图渲染前)和afterCompletion方法(请求完成后,用于资源清理)。 - 响应返回客户端
最终,渲染结果或序列化后的响应数据通过DispatcherServlet写回 HTTP 响应,返回给客户端。
83. 什么是拦截器(Interceptor)?如何实现?拦截器和过滤器有何区别?
拦截器(Interceptor)是 Spring MVC 提供的一种机制,用于在控制器方法执行前后插入自定义逻辑,其核心目的是将重复的横切关注点(如权限校验、日志记录)从业务代码中剥离出来。
什么是拦截器
Spring MVC 的拦截器基于 HandlerInterceptor 接口实现,它允许你在请求被处理器(Controller)处理的不同阶段介入。它的设计初衷是处理与处理器相关的细粒度预处理任务,例如权限检查或提取公共的处理器代码,而无需修改每一个处理器的实现。
如何实现拦截器
实现一个拦截器通常分为两步:定义拦截器类和注册拦截器。
1. 定义拦截器类
创建一个类实现 HandlerInterceptor 接口,并重写你需要的方法。该接口主要有三个方法:
preHandle:在处理器方法执行之前调用。返回true则放行,返回false则中断后续流程(后续拦截器和处理器都不会执行)。postHandle:在处理器方法执行之后、视图渲染之前调用。可以在此修改返回的ModelAndView。afterCompletion:在整个请求完成(视图渲染完毕)后调用,常用于资源清理。注意:只有当对应的preHandle返回true时,该方法才会被执行。
2. 注册拦截器
在 Spring Boot 中,通常通过一个配置类实现 WebMvcConfigurer 接口来注册,并可以指定拦截或排除的路径。
拦截器与过滤器的区别
两者功能相似,但属于不同规范,适用场景有别。核心区别如下:
| 对比维度 | 拦截器 (Interceptor) | 过滤器 (Filter) |
|---|---|---|
| 所属技术 | Spring MVC 框架的一部分 | Servlet 规范的一部分 |
| 作用范围 | 仅作用于 Spring MVC 处理的请求(即 DispatcherServlet 管理的请求) |
作用于所有进入 Servlet 容器的请求(包括静态资源等) |
| 依赖环境 | 需要 Spring MVC 环境 | 任何 Java Web 工程均可使用 |
| 执行时机 | 在 DispatcherServlet 内部,于处理器调用前后执行 |
在 DispatcherServlet 之前执行,更早介入请求 |
| 可访问对象 | 可以获取到即将执行的 处理器(Handler) 对象,便于进行与业务方法相关的精细控制 | 仅能访问 ServletRequest 和 ServletResponse,无法直接感知具体的控制器方法 |
| Spring 集成 | 是 Spring 管理的 Bean,可方便地使用依赖注入(DI) | 由 Servlet 容器管理,默认无法直接使用 Spring 的 DI(除非特殊配置) |

浙公网安备 33010602011771号