SpringBoot拦截器怎么用?从入门到实战的详细教程

 更新时间:2026年07月28日 08:41:11   作者:码农技术栈  
还在为SpringMVC中的横切关注点发愁?本文用快递分拣的通俗类比,带你彻底搞懂拦截器的定位、执行流程和实战用法,从登录验证到日志记录,揭秘拦截器如何优雅处理请求,并对比过滤器差异,让你轻松掌握拦截器核心技巧

“从请求到响应的守门人——揭秘如何用拦截器优雅处理横切关注点”

一、拦截器定位图解

快递分拣中心类比解析

拦截器就像快递分拣中心的质检流程,贯穿请求处理全链路:

  1. 客户端请求:快递包裹进入分拣中心
  2. 前置处理:检查包裹是否完好(如是否有破损、地址是否清晰)
  3. 控制器处理:按地址分拣到不同区域(处理具体业务逻辑)
  4. 后置处理:再次核对分拣结果(添加物流信息)
  5. 完成处理:包裹出库前的最终检查(记录处理日志)

二、拦截器 vs 过滤器

地铁安检 vs 小区门禁对比

特性拦截器(地铁安检)过滤器(小区门禁)
管辖范围只检查进站乘客(Spring MVC 路由)检查所有进出小区的人(所有请求)
依赖关系依赖地铁系统(Spring 上下文)独立于地铁(Servlet 容器)
检查权限能查乘客包里的地铁卡(@Autowired 获取 Bean)只能看身份证(需手动获取容器)
检查时机在候车厅前后(Controller 前后)在小区大门(Servlet 前后)
典型场景检查乘客是否携带违.禁.品(登录验证)登记所有访客信息(日志记录)

三、三步实现拦截器

1. 创建拦截器类

@Component
public class AuthInterceptor implements HandlerInterceptor {
    
    @Autowired
    private AuthService authService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) throws Exception {
        // 认证逻辑
        if (!authService.checkToken(request.getHeader("X-Token"))) {
            response.sendError(401, "未授权");
            return false; // 中断请求
        }
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, 
                         HttpServletResponse response, 
                         Object handler,
                         ModelAndView modelAndView) throws Exception {
        // 可修改ModelAndView
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, 
                              HttpServletResponse response, 
                              Object handler, 
                              Exception ex) throws Exception {
        // 资源清理
    }
}

2. 注册拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Autowired
    private AuthInterceptor authInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor)
            .addPathPatterns("/api/**")
            .excludePathPatterns("/api/login");
    }
}

3. 配置拦截路径

// 更精细的路径控制
registry.addInterceptor(new LogInterceptor())
    .addPathPatterns("/**")
    .excludePathPatterns("/static/**", "/error");

四、拦截器执行流程 🔄

快递包裹全流程质检图解

核心步骤详解

  1. preHandle(前置检查)
    像快递员检查包裹是否符合运输标准(如是否易燃易爆),返回 true 则继续处理,false 则直接拒绝(如未登录用户被拦截)。

  2. postHandle(后置核对)
    分拣员按地址分拣后,质检人员再次核对目的地(如订单金额计算后添加折扣信息),可修改响应内容。

  3. afterCompletion(完成处理)
    包裹出库后记录质检结果(如记录请求耗时、异常信息),即使中途出错也会执行(类似快递丢失后的追查记录)。

五、五大经典应用场景

1. 身份认证

public boolean preHandle(...) {
    String token = request.getHeader("Authorization");
    if(!jwtUtil.validateToken(token)) {
        response.sendError(401);
        return false;
    }
    return true;
}

2. 请求日志

public boolean preHandle(...) {
    long startTime = System.currentTimeMillis();
    request.setAttribute("startTime", startTime);
    log.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());
    return true;
}

public void afterCompletion(...) {
    long duration = System.currentTimeMillis() - (long)request.getAttribute("startTime");
    log.info("请求完成: 耗时{}ms", duration);
}

3. 参数预处理

public boolean preHandle(...) {
    if(request.getParameter("pageSize") == null) {
        request.setAttribute("pageSize", 10);
    }
    return true;
}

4. 响应统一包装

public void postHandle(...) {
    if(modelAndView != null) {
        modelAndView.addObject("timestamp", System.currentTimeMillis());
    }
}

5. 跨域支持

public boolean preHandle(...) {
    response.setHeader("Access-Control-Allow-Origin", "*");
    return true;
}

六、高级进阶技巧

1. 多拦截器顺序控制

registry.addInterceptor(i1).order(1);
registry.addInterceptor(i2).order(2); // 数字越小优先级越高

2. 注解驱动拦截

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuditLog {}

// 拦截器判断
if (handler instanceof HandlerMethod) {
    HandlerMethod hm = (HandlerMethod)handler;
    if (hm.hasMethodAnnotation(AuditLog.class)) {
        // 审计逻辑
    }
}

3. 异常处理

public void afterCompletion(...) {
    if(ex != null) {
        metrics.increment("error." + ex.getClass().getSimpleName());
    }
}

七、性能优化建议

  1. 轻量preHandle:前置处理尽量快速
  2. 异步处理:耗时操作放到afterCompletion
  3. 缓存验证结果:避免重复认证
  4. 合理排序:高频拦截器放前面

八、常见问题解答

Q1:拦截器能获取请求体吗?

A:可以,但需要包装Request重复读取:

ContentCachingRequestWrapper wrapper = new ContentCachingRequestWrapper(request);
byte[] body = wrapper.getContentAsByteArray();

Q2:如何跳过静态资源?

.excludePathPatterns("/static/**", "/favicon.ico")

Q3:拦截器vs切面怎么选?

  • 拦截器:处理HTTP相关逻辑(头信息、参数等)
  • 切面:处理业务逻辑(日志、事务等)

九、Spring Boot增强配置

# 控制拦截器顺序
spring.mvc.interceptor.order=0

# 开发环境打印拦截路径
logging.level.org.springframework.web.servlet.HandlerMapping=DEBUG

十、最新趋势展望

  1. WebFlux支持:响应式拦截器
  2. GraalVM适配:原生镜像中的优化
  3. AI集成:智能路由拦截
  4. 服务网格:与Istio等方案的协同

统计显示:企业级应用中平均每个项目使用3-5个拦截器

十一、总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Spring Cloud Stream处理事件的示例详解

    使用Spring Cloud Stream处理事件的示例详解

    Spring Cloud Stream 是基于 Spring Boot 的用于构建消息驱动微服务的框架,本文主要介绍了如何使用 Spring Cloud Stream 来处理事件,需要的可以参考一下
    2023-06-06
  • springBoot集成redis的key,value序列化的相关问题

    springBoot集成redis的key,value序列化的相关问题

    这篇文章主要介绍了springBoot集成redis的key,value序列化的相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Android 单例模式 Singleton 简单实例设计模式解析

    Android 单例模式 Singleton 简单实例设计模式解析

    这篇文章主要介绍了单例模式 Singleton 简单实例设计模式解析的相关资料,需要的朋友可以参考下
    2016-12-12
  • SpringBoot中实现定时任务的4种方式详解

    SpringBoot中实现定时任务的4种方式详解

    这篇文章主要介绍了SpringBoot中实现定时任务的4种方式详解,在Springboot中定时任务是一项经常能用到的功能,实现定时任务的方式有很多,今天来介绍常用的几种,需要的朋友可以参考下
    2023-11-11
  • Java使用Thread创建多线程并启动操作示例

    Java使用Thread创建多线程并启动操作示例

    这篇文章主要介绍了Java使用Thread创建多线程并启动操作,结合实例形式分析了Java基于Thread类的多线程定义与启动简单操作技巧,需要的朋友可以参考下
    2018-06-06
  • Java创建型设计模式之工厂方法模式深入详解

    Java创建型设计模式之工厂方法模式深入详解

    工厂方法模式(FACTORY METHOD)是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂、具体工厂、抽象产品、具体产品
    2022-09-09
  • 如何解决@value获取不到yaml数组的问题

    如何解决@value获取不到yaml数组的问题

    文章介绍了在使用YAML配置文件时,通过@Value注解获取整数和数组列表的配置方法,并提供了两种解决方案:一种适用于非嵌套列表,另一种适用于嵌套列表等复杂配置
    2024-11-11
  • Spring Cloud Gateway详细使用最佳实践

    Spring Cloud Gateway详细使用最佳实践

    Spring Cloud Gateway 是 Spring Cloud 生态系统中的现代化 API 网关组件,用于构建微服务架构中的统一入口网关,本文介绍Spring Cloud Gateway详细使用最佳实践,感兴趣的朋友一起看看吧
    2025-11-11
  • Java中实现高清图片压缩的两种方案(最新推荐)

    Java中实现高清图片压缩的两种方案(最新推荐)

    文章首先介绍了Java中进行高清图片压缩的基本方法,包括使用Java标准库ImageIO和第三方库ApacheCommonsCompress,通过示例代码展示了如何调整图像质量和使用第三方工具来压缩图片文件,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 通过代码实例了解SpringBoot启动原理

    通过代码实例了解SpringBoot启动原理

    这篇文章主要介绍了通过代码实例了解SpringBoot启动原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12

最新评论