写点什么

Spring 拦截器:你的请求休想逃过我的五指山!

  • 2025-07-18
    北京
  • 本文字数:2449 字

    阅读完需:约 8 分钟

拦截器概述

在 Spring 框架中,拦截器(Interceptor)是一种强大的机制,它允许开发者在请求处理的不同阶段插入自定义逻辑。WebApplicationContext 作为 Spring Web 应用的上下文容器,为拦截器的配置和管理提供了基础支持。


拦截器主要作用于以下场景:


权限验证


日志记录


性能监控


事务管理


通用行为注入等

拦截器与 WebApplicationContext 的关系

WebApplicationContext 是 Spring Web 应用的 IoC 容器扩展,它继承自 ApplicationContext,并添加了 Web 应用特有的功能。拦截器通过 WebApplicationContext 进行注册和管理,成为请求处理管道的一部分。


public interface WebApplicationContext extends ApplicationContext {    String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";        ServletContext getServletContext();}
复制代码

拦截器类型

HandlerInterceptor

最常用的拦截器接口,定义了三个关键方法:


public interface HandlerInterceptor {    default boolean preHandle(HttpServletRequest request,                              HttpServletResponse response,                              Object handler) throws Exception {        return true;    }        default void postHandle(HttpServletRequest request,                           HttpServletResponse response,                           Object handler,                          ModelAndView modelAndView) throws Exception {    }        default void afterCompletion(HttpServletRequest request,                                HttpServletResponse response,                                Object handler,                                Exception ex) throws Exception {    }}
复制代码

AsyncHandlerInterceptor

HandlerInterceptor 的扩展,增加了异步处理的支持。

WebRequestInterceptor

与 HandlerInterceptor 类似,但提供了更通用的 WebRequest 抽象,不依赖于 Servlet API。

拦截器配置

XML 配置方式

 
复制代码

Java 配置方式

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {        @Override    public void addInterceptors(InterceptorRegistry registry) {        registry.addInterceptor(new LoggingInterceptor())                .addPathPatterns("/**")                .excludePathPatterns("/static/**");                registry.addInterceptor(new AuthInterceptor())                .addPathPatterns("/admin/**");    }}
复制代码

注解方式

@Componentpublic class MyInterceptor implements HandlerInterceptor {    // 实现方法}
@Configurationpublic class InterceptorConfig { @Autowired private MyInterceptor myInterceptor; @Bean public WebMvcConfigurer adapter() { return new WebMvcConfigurer() { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor); } }; }}
复制代码

拦截器执行流程

拦截器在 DispatcherServlet 的处理流程中扮演重要角色:


  • preHandle:在处理器执行前调用


返回 true 继续执行


返回 false 中断请求处理


  • postHandle:在处理器执行后,视图渲染前调用


可修改 ModelAndView


  • afterCompletion:在完整请求完成后调用


适合资源清理


高级拦截器特性

拦截器顺序控制

可以通过 order 属性控制多个拦截器的执行顺序:


registry.addInterceptor(new InterceptorA()).order(1);registry.addInterceptor(new InterceptorB()).order(2);
复制代码

路径匹配模式

支持 Ant 风格的路径模式:


  1. ? 匹配一个字符

  2. 匹配零个或多个字符

  3. ** 匹配零个或多个目录

异步请求处理

对于异步请求,afterConcurrentHandlingStarted 方法会被调用而不是 postHandle 和 afterCompletion。

拦截器与过滤器的区别

实际应用示例

日志拦截器

public class LoggingInterceptor implements HandlerInterceptor {        private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);        @Override    public boolean preHandle(HttpServletRequest request,                            HttpServletResponse response,                            Object handler) {        long startTime = System.currentTimeMillis();        request.setAttribute("startTime", startTime);        logger.info("Request URL: {} : Start Time={}",                    request.getRequestURL(), startTime);        return true;    }        @Override    public void afterCompletion(HttpServletRequest request,                                HttpServletResponse response,                                Object handler,                                Exception ex) {        long startTime = (Long) request.getAttribute("startTime");        long endTime = System.currentTimeMillis();        logger.info("Request URL: {} : End Time={} : Time Taken={}ms",                    request.getRequestURL(), endTime, (endTime - startTime));    }}
复制代码

认证拦截器

public class AuthInterceptor implements HandlerInterceptor {        @Override    public boolean preHandle(HttpServletRequest request,                            HttpServletResponse response,                            Object handler) throws Exception {                HttpSession session = request.getSession();        if (session.getAttribute("user") == null) {            response.sendRedirect("/login");            return false;        }        return true;    }}
复制代码

DEMO 实测效果

被拦截



未被拦截



发布于: 刚刚阅读数: 2
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
Spring 拦截器:你的请求休想逃过我的五指山!_京东科技开发者_InfoQ写作社区