尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Spring Boot 4 三大神器实战——过滤器、拦截器、监听器,从使用到源码深度解析

Spring Boot 4 三大神器实战——过滤器、拦截器、监听器,从使用到源码深度解析 过滤器、拦截器、监听器是 Spring Boot Web 开发的“三大神器”但它们的区别和执行顺序经常被混淆。本文将彻底讲清它们的本质、使用场景、执行顺序并结合源码解析 Spring Boot 4 是如何注册它们的。一、先给结论三者到底有什么区别组件归属作用范围执行时机典型场景Filter过滤器​Servlet 规范所有请求包括静态资源进入 Servlet 容器后、进入 Controller 前编码设置、XSS 过滤、跨域Interceptor拦截器​Spring MVC仅 Controller 请求DispatcherServlet 之后、Controller 前后登录校验、权限检查、日志记录Listener监听器​Servlet 规范容器生命周期 / 域对象事件触发时初始化资源、统计在线人数一句话总结Filter 是 Servlet 级别的Interceptor 是 Spring MVC 级别的Listener 是事件级别的。二、Filter 过滤器最底层的守门人1️⃣ 什么是 FilterFilter 是Servlet 规范定义的组件在请求进入 Servlet 容器后、进入 Controller 前执行。public interface Filter { void init(FilterConfig filterConfig); void doFilter(ServletRequest request, ServletResponse response, FilterChain chain); void destroy(); }2️⃣ 自定义 Filter编码过滤器示例Component public class EncodingFilter implements Filter { Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8); chain.doFilter(request, response); // 放行 } }关键点chain.doFilter()必须调用否则请求被拦截。3️⃣ 配置 Filter 顺序OrderComponent Order(1) public class FirstFilter implements Filter { // ... }数值越小优先级越高。4️⃣ 通过 FilterRegistrationBean 精确控制Configuration public class FilterConfig { Bean public FilterRegistrationBeanEncodingFilter encodingFilterRegistration() { FilterRegistrationBeanEncodingFilter registration new FilterRegistrationBean(); registration.setFilter(new EncodingFilter()); registration.addUrlPatterns(/api/*); // 只拦截 /api 路径 registration.setOrder(1); return registration; } }✅企业级推荐用FilterRegistrationBean精确控制 URL 和顺序。三、Interceptor 拦截器Spring MVC 的专属卫士1️⃣ 什么是 InterceptorInterceptor 是Spring MVC​ 提供的机制只拦截 Controller 请求不拦截静态资源。public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler); default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView); default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); }2️⃣ 自定义拦截器登录校验Component public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token request.getHeader(Authorization); if (token null || !token.startsWith(Bearer )) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; // 拦截 } return true; // 放行 } }3️⃣ 注册拦截器Configuration public class WebConfig implements WebMvcConfigurer { Autowired private LoginInterceptor loginInterceptor; Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/api/**) .excludePathPatterns(/api/login, /api/register); } }可以精确控制拦截路径和排除路径。四、Listener 监听器事件驱动的观察者1️⃣ 什么是 ListenerListener 用于监听Servlet 容器中的事件如容器启动 / 关闭Session 创建 / 销毁Request 创建 / 销毁2️⃣ 常用监听器类型监听器监听对象ServletContextListener应用启动 / 关闭HttpSessionListenerSession 创建 / 销毁ServletRequestListenerRequest 创建 / 销毁3️⃣ 自定义监听器统计在线人数Component public class OnlineUserListener implements HttpSessionListener { private static final AtomicInteger ONLINE_COUNT new AtomicInteger(0); Override public void sessionCreated(HttpSessionEvent se) { ONLINE_COUNT.incrementAndGet(); } Override public void sessionDestroyed(HttpSessionEvent se) { ONLINE_COUNT.decrementAndGet(); } public static int getOnlineCount() { return ONLINE_COUNT.get(); } }五、执行顺序非常重要1️⃣ 单次请求完整执行顺序请求进入 Servlet 容器 ↓ Filter 1 - doFilter (前置) ↓ Filter 2 - doFilter (前置) ↓ DispatcherServlet ↓ Interceptor - preHandle ↓ Controller 方法执行 ↓ Interceptor - postHandle ↓ Interceptor - afterCompletion ↓ Filter 2 - doFilter (后置) ↓ Filter 1 - doFilter (后置) ↓ 响应返回客户端Filter 在最外层Interceptor 在内层。2️⃣ 多个 Filter / Interceptor 的顺序FilterOrder或FilterRegistrationBean.setOrder()InterceptorWebMvcConfigurer.addInterceptors()的注册顺序六、实战IP 黑名单拦截器1️⃣ 黑名单拦截器Component public class BlackIpInterceptor implements HandlerInterceptor { private static final SetString BLACK_IPS Set.of(192.168.1.100, 10.0.0.50); Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String ip request.getRemoteAddr(); if (BLACK_IPS.contains(ip)) { response.setStatus(HttpStatus.FORBIDDEN.value()); return false; } return true; } }2️⃣ 注册Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(blackIpInterceptor).addPathPatterns(/**); }七、Spring Boot 4 是如何注册它们的源码级解析1️⃣ Filter 的注册Spring Boot 4 通过FilterRegistrationBean将 Filter 注册到Servlet 容器。关键类ServletContextInitializerFilterRegistrationBean2️⃣ Interceptor 的注册Interceptor 由DispatcherServlet管理通过HandlerMapping在请求映射时调用。关键类HandlerExecutionChainHandlerInterceptor3️⃣ Listener 的注册Listener 通过ServletContext注册由Servlet 容器直接管理。八、常见坑位总结❌ 坑1Filter 中注入 Spring Bean 为 null✅ 原因Filter 由 Servlet 容器创建早于 Spring 容器。✅ 解决用Component或FilterRegistrationBean注册。❌ 坑2Interceptor 拦截了静态资源✅ 原因未排除静态资源路径。✅ 解决excludePathPatterns(/static/**, /public/**)❌ 坑3Listener 中无法注入 Bean✅ 解决确保 Listener 由 Spring 管理Component❌ 坑4Filter 顺序混乱✅ 解决明确指定Order或setOrder()九、本篇总结Filter 是 Servlet 级别的Interceptor 是 Spring MVC 级别的Filter 拦截所有请求Interceptor 只拦截 ControllerListener 监听容器生命周期和域对象事件执行顺序Filter → Interceptor → Controller企业级推荐用 RegistrationBean 精确控制
返回列表