一、责任链模式本质与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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {long startTime = System.currentTimeMillis();request.setAttribute("startTime", startTime);log.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());return true; // 继续执行链}@Overridepublic 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 {@Overridepublic 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());@Overridepublic 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();@Overridepublic 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 {@Overridepublic 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;@Overridepublic boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) {return validators.stream().allMatch(validator -> validator.validate(request));} }
深度思考:尝试在拦截器中实现动态可配置的处理链,并通过管理界面实时调整拦截器顺序和开关状态。遇到技术难点欢迎在评论区交流讨论,觉得本文对你有帮助请点赞⭐收藏📌,关注获取更多Spring深度解析!