Spring 中的拦截链(Interceptor Chain)通常用于在请求处理的过程中插入额外的逻辑,比如日志记录、权限验证、性能监控等。拦截链的核心思想是通过 责任链模式(Chain of Responsibility Pattern) 将多个拦截器串联起来,每个拦截器都可以对请求进行处理或拦截。
在 Spring 中,拦截链的实现主要体现在以下两个场景:
- Spring MVC 中的拦截器(HandlerInterceptor)。
- Spring AOP 中的拦截器(MethodInterceptor)。
以下分别对这两种拦截链的实现进行详细说明。
1. Spring MVC 中的拦截链
Spring MVC 提供了 HandlerInterceptor
接口,用于在请求处理的不同阶段插入自定义逻辑。拦截器可以应用于控制器(Controller)的请求处理过程中。
(1)HandlerInterceptor
接口
HandlerInterceptor
接口定义了三个方法:
- preHandle:在控制器方法执行之前调用。如果返回
false
,则中断请求处理链。 - postHandle:在控制器方法执行之后、视图渲染之前调用。
- afterCompletion:在请求完成之后调用(视图渲染完成后),通常用于资源清理。
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
}
(2)拦截链的执行流程
Spring MVC 的拦截链由 DispatcherServlet
驱动,执行流程如下:
- preHandle:
- 按顺序调用所有拦截器的
preHandle
方法。 - 如果某个拦截器的
preHandle
返回false
,则后续拦截器和控制器方法都不会执行。
- 按顺序调用所有拦截器的
- 控制器方法执行:
- 如果所有拦截器的
preHandle
都返回true
,则执行控制器方法。
- 如果所有拦截器的
- postHandle:
- 按逆序调用所有拦截器的
postHandle
方法。
- 按逆序调用所有拦截器的
- 视图渲染:
- 渲染视图(如 JSP、Thymeleaf 等)。
- afterCompletion:
- 按逆序调用所有拦截器的
afterCompletion
方法。
- 按逆序调用所有拦截器的
(3)配置拦截器
可以通过实现 WebMvcConfigurer
接口或继承 WebMvcConfigurerAdapter
类来配置拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor());
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/secure/**");
}
}
(4)示例:日志拦截器
public class LoggingInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("Before handling request: " + request.getRequestURI());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("After handling request: " + request.getRequestURI());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("Request completed: " + request.getRequestURI());
}
}
2. Spring AOP 中的拦截链
Spring AOP 通过 动态代理 实现拦截链,支持方法级别的拦截。核心接口是 MethodInterceptor
。
(1)MethodInterceptor
接口
MethodInterceptor
是 AOP 联盟(AOP Alliance)定义的接口,用于在方法调用前后插入逻辑。
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
(2)拦截链的执行流程
Spring AOP 的拦截链由 ProxyFactory
或 ProxyFactoryBean
驱动,执行流程如下:
- 创建代理对象:
- 为目标对象创建代理(JDK 动态代理或 CGLIB 代理)。
- 调用拦截器:
- 按顺序调用所有拦截器的
invoke
方法。 - 每个拦截器可以决定是否继续执行链中的下一个拦截器或目标方法。
- 按顺序调用所有拦截器的
- 执行目标方法:
- 如果所有拦截器都允许继续执行,则调用目标方法。
- 返回结果:
- 将目标方法的返回值传递给拦截器链,最终返回给调用者。
(3)配置拦截器
可以通过 XML 或注解方式配置 AOP 拦截器。
示例:基于注解的 AOP 拦截器
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logMethodCall(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method: " + joinPoint.getSignature().getName());
Object result = joinPoint.proceed(); // 继续执行拦截链或目标方法
System.out.println("After method: " + joinPoint.getSignature().getName());
return result;
}
}
示例:基于 XML 的 AOP 拦截器
<bean id="loggingInterceptor" class="com.example.LoggingInterceptor" />
<aop:config>
<aop:pointcut id="serviceMethods" expression="execution(* com.example.service.*.*(..))" />
<aop:advisor advice-ref="loggingInterceptor" pointcut-ref="serviceMethods" />
</aop:config>
运行 HTML
3. Spring 拦截链的核心设计
无论是 Spring MVC 还是 Spring AOP,拦截链的核心设计都是基于 责任链模式:
- 每个拦截器都是一个独立的处理器,负责处理特定的逻辑。
- 拦截器之间通过链式调用串联起来,每个拦截器可以决定是否继续执行链中的下一个拦截器。
- 拦截链的执行顺序可以通过配置控制。
4. Spring MVC 拦截链 vs Spring AOP 拦截链
特性 | Spring MVC 拦截链 | Spring AOP 拦截链 |
---|---|---|
应用场景 | 主要用于 Web 请求处理。 | 主要用于方法级别的拦截。 |
核心接口 | HandlerInterceptor 。 | MethodInterceptor 。 |
执行时机 | 请求处理的不同阶段(如 preHandle)。 | 方法调用前后。 |
配置方式 | 通过 WebMvcConfigurer 配置。 | 通过 AOP 注解或 XML 配置。 |
依赖 | 依赖于 Spring MVC 框架。 | 依赖于 Spring AOP 框架。 |
总结
Spring 拦截链的实现基于责任链模式,分为 Spring MVC 拦截链和 Spring AOP 拦截链:
- Spring MVC 拦截链:用于 Web 请求处理,支持在请求处理的不同阶段插入逻辑。
- Spring AOP 拦截链:用于方法级别的拦截,支持在方法调用前后插入逻辑。
拦截链的设计使得 Spring 应用程序可以灵活地扩展功能,同时保持代码的模块化和可维护性。
暂无评论内容