在 Spring MVC 中,HandlerInterceptor 是一种常用的拦截器,用于在处理请求的不同阶段插入逻辑(如认证、日志记录等)。多个拦截器的执行顺序由它们的配置顺序决定。以下是配置和执行顺序的完整指南。
拦截器的执行阶段
preHandle:
- 在请求被处理之前调用。
- 返回
true 表示继续执行,返回 false 表示中断请求。
postHandle:
- 在请求处理之后,但在生成视图之前调用。
- 可以修改返回的数据。
afterCompletion:
拦截器的执行顺序
完整配置步骤
1. 创建拦截器类
实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter(已过时,推荐直接实现接口)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
@Component public class FirstInterceptor implements HandlerInterceptor {
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor - preHandle"); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor - postHandle"); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor - afterCompletion"); } }
|
类似的创建第二个拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Component public class SecondInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SecondInterceptor - preHandle"); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("SecondInterceptor - postHandle"); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("SecondInterceptor - afterCompletion"); } }
|
2. 配置拦截器顺序
在 WebMvcConfigurer 中添加拦截器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class WebConfig implements WebMvcConfigurer {
@Autowired private FirstInterceptor firstInterceptor;
@Autowired private SecondInterceptor secondInterceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(firstInterceptor) .addPathPatterns("/**") .order(1);
registry.addInterceptor(secondInterceptor) .addPathPatterns("/**") .order(2); } }
|
执行顺序
以请求 /example 为例,两个拦截器的执行顺序如下:
请求进入时:
FirstInterceptor - preHandleSecondInterceptor - preHandle
处理完成时:
SecondInterceptor - postHandleFirstInterceptor - postHandle
请求完成后:
SecondInterceptor - afterCompletionFirstInterceptor - afterCompletion
常见场景和配置
1. 拦截特定路径
1 2 3
| registry.addInterceptor(firstInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/login");
|
2. 优先级控制
order() 控制顺序:
order(1) 会在 order(2) 之前执行。- 如果未设置
order,默认顺序由添加的先后决定。
3. 动态逻辑中断请求
在 preHandle 返回 false 可以中断请求,例如:
1 2 3 4 5 6 7 8 9
| @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (!isAuthorized(request)) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.getWriter().write("Unauthorized"); return false; } return true; }
|
总结
- 顺序控制:通过
order() 明确拦截器的优先级,preHandle 按顺序,postHandle 和 afterCompletion 倒序。 - 灵活配置:支持路径匹配和排除规则。
- 统一管理:通过实现
WebMvcConfigurer 管理所有拦截器,逻辑清晰易维护。