尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

深入解析:Spring MVC 拦截器interceptor

深入解析:Spring MVC 拦截器interceptor
📅 发布时间:2026/6/19 19:46:25

深入解析:Spring MVC 拦截器interceptor

Spring MVC 过滤器interceptor

  • 拦截器
    • 定义
    • 概念与工作原理
    • **执行顺序**
      • 多拦截器执行顺序
    • 优势
  • 拦截器实现代码
    • xml 配置方式
      • 1. 实现HandlerInterceptor接口
      • 2. 配置XML文件,声明拦截路径
      • 3. 访问路径,触发拦截器
    • 配置类方式
      • 1. 实现HandlerInterceptor接口。
      • 2. 配置类实现webMvcConfigurer接口重载addInterceptors方法。
      • 3. 测试拦截器效果。
  • 拦截器 vs. 过滤器

示例代码地址:https://gitee.com/hua5h6m/framework-java/tree/master/spring-mvc-interceptor

拦截器三个方法拦截位置

拦截器

定义

Spring 拦截器 是 Spring MVC 框架提供的一种强大机制,它允许您在 HTTP 请求进入控制器 或 控制器处理完请求后以及最终返回给用户前,注入自定义的预处理和后处理逻辑。

概念与工作原理

拦截器的工作流程基于 AOP 的设计思想,它围绕着 控制器方法的执行 进行拦截。

一个完整的拦截器生命周期包含三个关键时机点:

  1. preHandle - 预处理:决定是否拦截,返回值为Boolean类型。

    • 时机:在请求被 DispatcherServlet 接收后,但在调用目标 Controller(Handler)方法 之前 执行。
    • 作用:这是最常用、最重要的方法。常用于:
      • 权限验证:检查用户是否登录,是否有权限访问该接口。
      • 日志记录:记录请求信息,如 URL、IP、参数等。
      • 性能监控:记录请求开始时间。
      • 参数预处理:对请求参数进行统一的格式化或校验。
    • 返回值:boolean 类型。
      • true:继续执行流程,调用下一个拦截器或最终的 Controller 方法。
      • false:中断请求,不再继续向下执行。通常在此方法中直接通过 response 返回结果。
  2. postHandle - 后处理

    • 时机:在 Controller 方法执行 之后,但在视图渲染或返回 JSON 之前 执行。
    • 作用:
      • 对 Controller 返回的 ModelAndView 对象进行修改(例如,向模型中添加一些全局数据)。
      • 在返回视图前进行一些处理。
    • 注意:如果 Controller 方法内部发生了异常,此方法将 不会 被调用。
  3. afterCompletion - 请求完成回调

    • 时机:在整个请求完成 之后,即视图渲染完毕或响应已返回给客户端 之后 执行。
    • 作用:
      • 资源清理:如清理 preHandle 中创建的线程局部变量。
      • 性能监控收尾:计算整个请求的耗时(需要与 preHandle 中记录的开始时间配合)。
      • 记录最终日志。
    • 注意:无论 Controller 方法执行是否成功,此方法 总会被调用(类似于 try-catch-finally 中的 finally 块)。

执行顺序

Filter.doFilter() -> DispatcherServlet -> Interceptor.preHandle() -> Controller -> Interceptor.postHandle() -> 渲染视图 -> Interceptor.afterCompletion()


多拦截器执行顺序

在Spring MVC中,当存在多个拦截器时,它们的执行顺序由配置的先后顺序决定。具体来说,在配置类中通过InterceptorRegistry添加拦截器的顺序就是拦截器的执行顺序。或者在XML中,谁先配置谁先执行。

假设我们有两个拦截器:InterceptorA和InterceptorB,并且我们先添加InterceptorA,再添加InterceptorB。

  • 正常情况下的执行顺序(所有拦截器的preHandle都返回true):
  1. InterceptorA.preHandle()
  2. InterceptorB.preHandle()
  3. 执行控制器方法(Handler)
  4. InterceptorB.postHandle()
  5. InterceptorA.postHandle()
  6. InterceptorB.afterCompletion()
  7. InterceptorA.afterCompletion()

注意:preHandle方法是按照配置顺序执行的,而postHandle和afterCompletion则是按照配置顺序的反向顺序执行。先进后出原则。

优势

  • 核心概念:Spring 拦截器是 Spring MVC 中用于在控制器方法执行前后插入逻辑的组件。
  • 生命周期:包含 preHandle(最常用)、postHandle 和 afterCompletion 三个关键方法。
  • 主要应用:权限校验、日志记录、性能监控、通用参数处理 等横切关注点。
  • 核心优势:将通用的、非业务性的代码从业务控制器中解耦出来,使代码更加清晰、可维护和可复用。

拦截器实现代码

xml 配置方式

1. 实现HandlerInterceptor接口

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle:handler触发之前");
return true;
}
@Override
public void postHandle(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle:handler触发之后");
}
@Override
public void afterCompletion(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion:");
}
}

2. 配置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.maven" /><!--配置控制器映射器和控制器适配器--><mvc:annotation-driven /><!--配置静态资源解析--><mvc:default-servlet-handler /><!--配置拦截器--><mvc:interceptors><!--第一个拦截器--><mvc:interceptor><!--拦截那些路径:默认全部拦截--><mvc:mapping path="/user/**"/><!--配置不拦截的路径--><mvc:exclude-mapping path="/user/list"/><!--指定拦截器的位置--><bean class="com.maven.interceptor.UserInterceptor" /></mvc:interceptor></mvc:interceptors></beans>

3. 访问路径,触发拦截器

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("info")
public String info() {
return "user info";
}
@GetMapping("list")
public String list() {
return "user list";
}
@GetMapping("exception")
public String exception() {
int i = 1 / 0;
return "user exception";
}
}
  • 访问/user/info,链接返回结果:
preHandle
postHandle
afterCompletion
  • 访问/user/exception,链接返回结果:
  • 页面报错500,因此postHandler不会触发,但是afterCompletion无论是否出现异常,都会执行。
preHandle
afterCompletion

配置类方式

1. 实现HandlerInterceptor接口。

  • 通过@Component注解,添加到容器中。
@Component
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}

2. 配置类实现webMvcConfigurer接口重载addInterceptors方法。

  • 一定不能忘记添加@Configuration注解。
  • 实现接口WebMvcConfigurer 接口,并重载addInterceptors方法。
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Autowired
private UserInterceptor userInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor).addPathPatterns("/user/**");
}
}

3. 测试拦截器效果。

@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("info")
public String info(){
return "user info"+ new Date();
}
}
  • 结果输出:
preHandle
postHandle
afterCompletion

拦截器 vs. 过滤器

这是一个非常常见的面试题,理解它们的区别至关重要。

特性Spring 拦截器Servlet 过滤器
出身Spring 框架 特有的组件。Servlet 规范 的一部分,任何 Java Web 应用都能用。
依赖依赖于 Spring 容器。不依赖于 Spring,只依赖于 Servlet 容器(如 Tomcat)。
作用域只能拦截 Spring MVC 的请求(即 DispatcherServlet 处理的请求)。可以拦截 所有 进入容器的请求(包括静态资源、JSP等)。
获取Bean可以轻松获取和注入 Spring 容器中的其他 Bean(如 Service)。默认不能,需要通过 SpringBeanAutowiringSupport 等特殊方式。
控制粒度可以获取到具体的 Handler(控制器方法) 信息。只能获取到 ServletRequest 和 ServletResponse。
执行时机在 DispatcherServlet 内部,Controller 方法执行的前后。在 DispatcherServlet 之前。

相关新闻

  • 《重生之我成为世界顶级黑客》第八章:未来野望
  • 打开工作空间时,但未在 DTD/架构中声明
  • 从 LLM 到 Agentic AI:构建下一代智能平台的全栈路径

最新新闻

  • Onekey完整教程:一键解锁Steam游戏DLC的终极方案
  • 2026年南京知名3D效果图制作公司大盘点,你知道几家?
  • S12 MSCAN与SCI模块深度解析:低功耗、中断与安全初始化实战
  • MPV播放器懒人包:3分钟打造专业级视频播放体验
  • 2026年6月经验丰富的升降货梯生产公司哪家便宜,导轨式货梯升降机/厂房升降货梯/四柱液压货梯,升降货梯工厂平价推荐 - 品牌推荐师
  • 4.19周总结

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号