拦截器概述
在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。
拦截器配置
Java配置方式public class WebConfig implements WebMvcConfigurer {public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**").excludePathPatterns("/static/**");registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/admin/**");}}
注解方式
public class MyInterceptor implements HandlerInterceptor {// 实现方法}public class InterceptorConfig {private MyInterceptor myInterceptor;public WebMvcConfigurer adapter() {return new WebMvcConfigurer() {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.匹配一个字符
3.匹配零个或多个目录
异步请求处理
对于异步请求,afterConcurrentHandlingStarted方法会被调用而不是postHandle和afterCompletion。
拦截器与过滤器的区别
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
实际应用示例
日志拦截器
public class LoggingInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);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;}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 {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实测效果
被拦截
未被拦截

