题目
Spring MVC拦截器的实现原理与应用场景
信息
- 类型:问答
- 难度:⭐⭐
考点
拦截器工作原理,生命周期控制,实际应用场景
快速回答
HandlerInterceptor是Spring MVC的核心扩展点,用于在请求处理的不同阶段注入自定义逻辑。主要应用包括:
- 权限验证:在Controller执行前检查用户权限
- 日志记录:记录请求耗时和参数
- 通用处理:设置/清理线程局部变量
实现需重写三个核心方法:preHandle()、postHandle()和afterCompletion()。
解析
一、拦截器原理说明
HandlerInterceptor基于责任链模式工作,在请求处理流程的关键节点插入钩子:
- preHandle:Controller方法执行前触发,返回boolean决定是否继续流程
- postHandle:Controller执行后、视图渲染前触发
- afterCompletion:请求完成后的最终回调(无论成功或异常)
二、代码示例
1. 基础拦截器实现:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 权限验证逻辑
if (!checkUserAuth(request)) {
response.sendRedirect("/login");
return false; // 中断请求
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) {
// 添加全局模型数据
modelAndView.addObject("version", "1.0.0");
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
// 清理线程局部变量
UserContext.clear();
}
}2. 注册拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/api/**") // 拦截路径
.excludePathPatterns("/api/public/**"); // 排除路径
}
}三、典型应用场景
- 身份认证:验证JWT令牌或Session状态
- 性能监控:在preHandle记录开始时间,afterCompletion计算耗时
- 防重复提交:通过令牌机制校验重复请求
- 国际化处理:根据请求头设置Locale
四、最佳实践
- 执行顺序控制:通过
Order接口或@Order注解管理多个拦截器的顺序 - 路径匹配优化:使用Ant风格路径表达式精确匹配URL
- 资源释放:在
afterCompletion中确保释放数据库连接等资源 - 异步请求处理:对
AsyncHandlerInterceptor的实现需额外处理afterConcurrentHandlingStarted
五、常见错误
- 循环重定向:在preHandle中未正确中断未认证请求导致死循环
- 线程安全问题:错误使用成员变量而非线程局部变量
- 异常处理缺失:未在afterCompletion中清理异常状态资源
- 性能损耗:在拦截器中执行耗时数据库操作阻塞请求
六、扩展知识
- 与Filter的区别:Filter属于Servlet规范,更底层但无法访问Spring上下文;拦截器可获取HandlerMethod等Spring元数据
- 异步支持:实现
AsyncHandlerInterceptor可处理异步请求生命周期 - 参数解析扩展:结合
HandlerMethodArgumentResolver实现自动注入自定义参数 - 新版变化:Spring 5.3+ 新增
default方法简化实现