在构建Web应用时,统一处理用户请求的登录校验、权限验证和日志记录是常见需求。Spring Boot拦截器(Interceptor)正是解决这类问题的利器。本文将带你深入理解拦截器的原理、实现方式及执行流程,助你快速掌握这一关键技能。
1. 为什么需要拦截器?从图书管理系统的痛点说起
假设你正在开发一个图书管理系统,需要实现强制登录功能——用户必须登录后才能访问其他页面。传统做法是在每个接口中手动编写Session校验逻辑,但这会带来三个问题:
- 代码冗余:每个接口都需要重复编写校验代码,维护成本高。
- 耦合性强:业务逻辑与校验逻辑混杂,修改一处可能影响全局。
- 前后端联动复杂:接口定义变更时,前端代码也需要同步调整。
有没有更优雅的解决方案?答案是使用拦截器。它允许你在请求到达Controller之前统一执行预定义逻辑,如Session校验、权限检查等,从而将通用功能从业务代码中剥离出来。
2. 什么是拦截器?用生活场景来理解
拦截器是Spring框架提供的核心功能之一,主要用于拦截用户请求,在目标方法执行前后执行预设代码。以下是两个生活化的例子:
场景一:大学校园的人脸识别门禁
学生回校时,需通过人脸识别验证身份;校外访客则需保安登记信息。无论是人脸识别还是保安登记,都是在进入校园(执行目标操作)前的“拦截”环节。拦截器的作用与此类似:在请求到达Controller前,执行校验逻辑,决定是否放行。
场景二:银行办理业务
办理业务前需取号并验证身份证,业务结束后需评价服务。这些“前置”和“后置”操作正是拦截器的典型应用。通过拦截器,你可以在请求处理前后添加通用逻辑,如日志记录、性能监控等。
核心定义:拦截器允许开发人员预定义逻辑,在用户请求响应前后执行,或在请求前阻止其执行。例如,判断Session中是否存在登录用户信息:
- ✅ 有:放行请求。
- ❌ 无:拦截请求并返回提示。

3. 拦截器的基本使用:两步搞定
在Spring Boot中,使用拦截器只需两步:定义拦截器和注册配置拦截器。下面以图书管理系统为例进行演示。
3.1 定义拦截器
创建一个intercepter包,定义LoginIntercepter类,实现HandlerInterceptor接口并重写方法:
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
@Component
public class LoginIntercepter implements HandlerInterceptor {
/**
*
* @param request
* @param response
* @param handler
* @return
* true:对目标方法放行,不会拦截
* false:拦截目标方法,通过验证之后,才能访问
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception {
log.info("preHandle方法,目标方法执行前。。。");
// true: 放行目标方法
// false:拦截目标方法
return true;
}
@Override
public void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView modelAndView) throws Exception {
log.info("postHandle方法,目标方法执行后!!!");
HandlerInterceptor.super.postHandle(request,response,handler,modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception ex) throws Exception {
log.info("LoginInterceptor 视图渲染完毕后执行,最后执行");
HandlerInterceptor.super.afterCompletion(request,response,handler,ex);
}
}
HandlerInterceptor接口包含三个方法:
- preHandle():在目标方法执行前调用。返回
true表示放行,返回false表示拦截。 - postHandle():在目标方法执行后、视图渲染前调用。
- afterCompletion():在视图渲染完毕后执行,是整个请求处理流程的最后一步。
3.2 注册配置拦截器
创建一个config包,定义WebConfig类,实现WebMvcConfigurer接口并重写addInterceptors方法:
import lombok.extern.slf4j.Slf4j;
import org.example.book_system_20251107.book.intercepter.LoginIntercepter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Slf4j
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginIntercepter loginIntercepter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
log.info("拦截器启动拦截");
registry.addInterceptor(loginIntercepter).addPathPatterns("/**");
// 这句代码做了两件事情:
// 1. 添加拦截器对象,指定使用的拦截器
// 2. 设置拦截器拦截的请求路径( /** 表⽰拦截所 有请求)
}
}
⚠️ 重要提示:WebConfig类必须添加@Configuration注解,否则addInterceptors方法不会执行,拦截器也不会生效。

常见拦截路径配置:
/**:拦截所有请求路径。/book/**:拦截路径中包含book的所有请求。

4. 测试拦截器:放行与拦截的对比
启动图书管理系统,使用Postman测试登录接口(URL = http://127.0.0.1:8080/user/login name=admin&password=admin):
4.1 返回true:放行
当preHandle()返回true时,请求被放行,正常执行Controller中的方法:


4.2 返回false:拦截
当preHandle()返回false时,请求被拦截,不会执行后续任何操作:


在实际开发中,你需要在拦截器中编写业务逻辑来判断是否拦截。例如,检查Session中是否存在用户信息:
- 存在:返回true,放行。
- 不存在:返回false,并返回提示信息。
排除拦截请求:拦截器还支持排除特定路径,例如登录页、注册页等。这一功能将在后续文章(图书管理系统(7)完善强制登录功能)中详细演示。
[AFFILIATE_SLOT_1]5. 拦截器执行流程:从请求到响应的完整路径
理解拦截器的执行流程至关重要。以下是添加拦截器前后的对比:
5.1 无拦截器时的调用顺序
请求直接到达Controller,执行方法后返回响应:

5.2 有拦截器时的调用顺序
请求先被拦截器拦截,执行preHandle()方法:
- 返回true:放行,继续执行Controller中的方法。
- 返回false:拦截,Controller中的方法不会执行。
Controller方法执行完毕后,依次执行postHandle()和afterCompletion()方法,最后返回响应给客户端。

5.3 拦截器与过滤器的执行顺序
当同时存在拦截器(Interceptor)和过滤器(Filter)时,执行顺序如下:
- Filter → Interceptor.preHandle() → Controller → Interceptor.postHandle() → Interceptor.afterCompletion() → Filter后续逻辑

技术要点:在Java、JavaScript、C++、Go、TypeScript等语言中,拦截器(或中间件)的概念类似,都是用于在请求处理管道中插入通用逻辑。Spring Boot的拦截器实现与这些语言的中间件设计思想一脉相承。
[AFFILIATE_SLOT_2]6. 总结:拦截器的核心价值
本文从图书管理系统的痛点出发,详细介绍了Spring Boot拦截器的概念、使用方法和执行流程。拦截器的核心价值在于:
- 统一处理:将登录校验、权限验证、日志记录等通用逻辑集中管理。
- 解耦业务:避免业务代码与基础设施代码混杂,提升可维护性。
- 灵活控制:支持放行、拦截和路径排除,满足复杂业务需求。
下一篇我们将探讨统一数据返回格式,敬请期待!
浙公网安备 33010602011771号