过滤器一定在拦截器之前执行,且都在dispatcherservlet之前或之内按既定流程运转;过滤器属servlet规范,由容器管理,拦截所有请求;拦截器属spring mvc机制,仅作用于controller层请求。

Spring MVC 中拦截器和过滤器本身没有直接配置“谁先谁后”的开关,它们的执行顺序由底层架构决定,是固定的、不可更改的。简单说:过滤器一定在拦截器之前执行,且都在 DispatcherServlet 之前或之内按既定流程运转。
理解这个顺序,关键不是“怎么配”,而是搞清它们所处的位置和触发时机。
过滤器(Filter)总是在最外层
Filter 属于 Servlet 规范,由 Servlet 容器(如 Tomcat)管理,它包裹整个 Web 应用的请求入口。
- 所有 HTTP 请求进来,最先经过 Filter 链
- Filter 可以处理任意资源:
.html、.js、静态文件、Servlet、Spring MVC 的所有请求 - 它不依赖 Spring 容器,不能直接注入
@Service或@AutowiredBean - 常见用途:统一编码设置(
CharacterEncodingFilter)、XSS 过滤、跨域头添加、请求日志记录
配置方式(以 Java 配置为例):
@Bean
public FilterRegistrationBean<characterencodingfilter> encodingFilter() {
FilterRegistrationBean<characterencodingfilter> registration = new FilterRegistrationBean();
registration.setFilter(new CharacterEncodingFilter());
registration.setOrder(Ordered.HIGHEST_PRECEDENCE); // 数值越小,越早执行
registration.addUrlPatterns("/*");
return registration;
}</characterencodingfilter></characterencodingfilter>
⚠️ 注意:多个 Filter 的执行顺序靠 setOrder() 控制,Ordered.HIGHEST_PRECEDENCE = Integer.MIN_VALUE,Ordered.LOWEST_PRECEDENCE = Integer.MAX_VALUE。
拦截器(Interceptor)只作用于 Spring MVC 流程内
Interceptor 是 Spring MVC 自己的机制,只有请求真正进入 DispatcherServlet 后才会触发。
- 它只拦截 Controller 层的请求(即匹配到
@RequestMapping的路径) - 不处理静态资源(除非你显式配置
/**并开启静态资源映射) - 完全属于 Spring 容器,支持依赖注入、AOP、事务等 Spring 特性
- 一个请求可被多个 Interceptor 拦截,按注册顺序链式执行
配置方式(Java 配置):
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns("/login", "/static/**"); // 排除路径
registry.addInterceptor(new LogInterceptor())
.order(1); // order 越小,preHandle 越早执行
}
}
✅ 多个 Interceptor 的 preHandle() 按 order 升序执行;postHandle() 和 afterCompletion() 则逆序执行(类似栈)。
它们的完整执行流程(一次请求)
HTTP 请求
↓
→ Filter#doFilter() 【前置】(可多次,按 order 顺序)
↓
→ DispatcherServlet 入口
↓
→ Interceptor#preHandle() 【按 order 升序】(任一返回 false,后续全跳过)
↓
→ Controller 方法执行
↓
→ Interceptor#postHandle() 【按 order 降序】(仅 preHandle 返回 true 的才执行)
↓
→ View 渲染(JSP/Thymeleaf)或 JSON 返回
↓
→ Interceptor#afterCompletion() 【按 order 降序】(总会执行,含异常情况)
↓
→ Filter#doFilter() 【后置】(chain.doFilter 后的代码)
↓
HTTP 响应
所以:
- Filter 包裹整个流程,像一层“外壳”
- Interceptor 是 DispatcherServlet 内部的“夹层”,只对 MVC 请求生效
- 二者不重叠控制权,也无需“协调顺序”——它们天然分层
实际开发中要注意的点
- 如果要做登录校验,推荐用 Interceptor:能注入
UserService、读取 session、跳转页面,更灵活 - 如果要做字符编码或请求体解密,必须用 Filter:因为 Controller 还没启动,
request.getInputStream()只能在这里读一次 - 不要试图在 Filter 里调用
@Service,它不是 Spring Bean;如需 Spring 上下文,可用WebApplicationContextUtils.getRequiredWebApplicationContext()(不推荐,耦合重) - 前后端分离项目(返回 JSON),
postHandle几乎无用(没 ModelAndView),重点用preHandle和afterCompletion
基本上就这些。











