Spring MVC拦截器中的责任链模式深度解析
一、责任链模式本质与Spring MVC拦截器的设计契合
1.1 责任链模式核心思想
责任链模式(Chain of Responsibility)是一种行为型设计模式,其核心在于将请求的发送者和接收者解耦,允许多个对象都有机会处理请求。典型的责任链模式包含三个关键角色:
-
Handler(抽象处理者):定义处理请求的接口
-
ConcreteHandler(具体处理者):实现具体处理逻辑
-
Client(客户端):组装处理链并触发请求
1.2 Spring MVC拦截器架构
Spring MVC拦截器的实现完美体现了责任链模式的设计思想:
二、Spring MVC拦截器链的源码级解析
2.1 HandlerExecutionChain核心源码
public class HandlerExecutionChain { private final List<HandlerInterceptor> interceptorList = new ArrayList<>(); boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { for (int i = 0; i < this.interceptorList.size(); i++) { HandlerInterceptor interceptor = this.interceptorList.get(i); if (!interceptor.preHandle(request, response, handler)) { triggerAfterCompletion(request, response, handler, null); return false; } this.interceptorIndex = i; } return true; } void applyPostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { for (int i = this.interceptorList.size() - 1; i >= 0; i--) { HandlerInterceptor interceptor = this.interceptorList.get(i); interceptor.postHandle(request, response, handler, modelAndView); } } }
2.2 拦截器链的三大执行阶段
-
preHandle正向遍历执行(控制器方法前)
-
postHandle逆向遍历执行(控制器方法后,视图渲染前)
-
afterCompletion正向遍历执行(请求完成时,包括异常情况)
三、自定义拦截器链实现方案
3.1 基础拦截器实现
public class LogInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); log.info("请求开始: {} {}", request.getMethod(), request.getRequestURI()); return true; // 继续执行链 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { long duration = System.currentTimeMillis() - (long) request.getAttribute("startTime"); log.info("请求完成: {} 耗时{}ms", request.getRequestURI(), duration); } }
3.2 高级链式配置
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/login"); registry.addInterceptor(new LogInterceptor()) .order(Ordered.HIGHEST_PRECEDENCE); registry.addInterceptor(new PerformanceInterceptor()) .order(Ordered.LOWEST_PRECEDENCE); } }
四、责任链模式在拦截器中的典型应用场景
4.1 权限校验链
4.2 请求处理流水线
public class ProcessingChainInterceptor implements HandlerInterceptor { private List<RequestProcessor> processors = Arrays.asList( new ValidationProcessor(), new CachingProcessor(), new TransformationProcessor() ); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { for (RequestProcessor processor : processors) { if (!processor.process(request)) { return false; } } return true; } }
五、高级特性与最佳实践
5.1 拦截器链中断机制
public class CircuitBreakerInterceptor implements HandlerInterceptor { private CircuitBreaker circuitBreaker = new CircuitBreaker(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (circuitBreaker.isOpen()) { response.sendError(HttpStatus.SERVICE_UNAVAILABLE.value()); return false; // 中断请求处理 } return true; } }
5.2 异步请求处理
public class AsyncInterceptor implements AsyncHandlerInterceptor { @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) { log.info("进入异步处理模式"); } }
5.3 性能优化建议
-
拦截器排序:高频拦截器靠前执行
-
避免阻塞操作:不在preHandle中进行IO密集型操作
-
缓存重复计算:利用ThreadLocal缓存跨拦截器数据
-
合理使用短路:及时中断无效请求
六、与过滤器(Filter)的责任链对比
对比维度 | 拦截器(Interceptor) | 过滤器(Filter) |
---|---|---|
作用范围 | Spring MVC上下文 | Servlet容器级别 |
依赖关系 | 需要Spring容器支持 | 不依赖Spring |
执行时机 | Controller方法前后 | 请求进入DispatcherServlet前 |
访问对象 | 可以获取Handler信息 | 只能获取Servlet API对象 |
异常处理 | 可以通过@ControllerAdvice处理 | 需要通过web.xml配置错误页面 |
七、源码级调试技巧
7.1 关键断点设置
-
DispatcherServlet#doDispatch
-
HandlerExecutionChain#applyPreHandle
-
AbstractHandlerMapping#getHandler
7.2 执行流程观察
八、企业级实践总结
8.1 设计原则
-
单一职责:每个拦截器专注一个功能点
-
开闭原则:新增功能通过添加拦截器实现
-
可配置化:通过配置文件管理拦截器开关
8.2 常见陷阱
-
顺序依赖:错误配置拦截器执行顺序导致逻辑错误
-
线程安全:错误使用成员变量引发并发问题
-
性能黑洞:在拦截器中执行重量级操作影响吞吐量
-
异常处理:未正确处理preHandle返回false的情况
8.3 最佳实践
// 使用组合模式封装多个校验器 public class CompositeValidatorInterceptor implements HandlerInterceptor { private List<RequestValidator> validators; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { return validators.stream() .allMatch(validator -> validator.validate(request)); } }
深度思考:尝试在拦截器中实现动态可配置的处理链,并通过管理界面实时调整拦截器顺序和开关状态。遇到技术难点欢迎在评论区交流讨论,觉得本文对你有帮助请点赞⭐收藏📌,关注获取更多Spring深度解析!