You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中过滤器注册@Component与@WebFilter的使用疑惑

Spring Boot中过滤器注册@Component与@WebFilter的使用疑惑

嗨,我来帮你理清这个过滤器注册的困惑!其实这个问题的核心在于Spring Boot对Servlet组件(过滤器、Servlet、Listener)的扫描机制,我给你拆解一下:

为什么有些博客只用@WebFilter就能生效?

你看到的那些只用@WebFilter就成功注册过滤器的案例,一定是在Spring Boot的启动类上加了@ServletComponentScan注解!这个注解的作用就是让Spring Boot扫描指定包下带有@WebFilter、@WebServlet、@WebListener的类,并把它们注册到Servlet容器中。很多博客可能默认你知道这个前置条件,所以没特意写出来,才导致你疑惑。

如果你的启动类没加@ServletComponentScan,那单独加@WebFilter的过滤器类根本不会被Spring Boot识别,自然不会生效。

为什么你需要同时用@Component和@WebFilter?

你当前的情况应该是启动类没有加@ServletComponentScan,这时候@Component的作用是把你的XssFilter纳入Spring的Bean管理容器,而@WebFilter里的urlPatterns、filterName这些配置会被Spring读取并应用到这个Bean上,最终实现过滤器的注册和拦截。

不过这里要注意:这种方式其实是Spring的“兼容处理”,本质上是把过滤器作为Spring Bean注册,同时复用了@WebFilter的配置信息,但并不是标准的Servlet组件注册方式。

两种推荐的正确注册方式

给你推荐两种更清晰、不会踩坑的过滤器注册方式:

方式一:@WebFilter + @ServletComponentScan

  1. 过滤器类只保留@WebFilter注解:
@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
public class XssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
  1. 在Spring Boot启动类上添加@ServletComponentScan,指定过滤器所在的包(不指定的话默认扫描启动类所在包及其子包):
@SpringBootApplication
@ServletComponentScan(basePackages = "com.yourpackage.filter")
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

方式二:@Component + FilterRegistrationBean(更灵活)

这种方式完全不用@WebFilter,通过Spring的配置类手动注册过滤器,能更精细地控制过滤器的顺序、拦截规则等:

  1. 过滤器类只加@Component:
@Component
public class XssFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
  1. 创建一个配置类,用FilterRegistrationBean来注册:
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<XssFilter> xssFilterRegistration(XssFilter xssFilter) {
        FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(xssFilter);
        registration.addUrlPatterns("/*"); // 设置拦截路径
        registration.setName("xssFilter"); // 设置过滤器名称
        registration.setOrder(1); // 设置执行顺序,值越小越先执行
        return registration;
    }
}

关于SSM项目的补充(你提到没写完的部分)

在传统SSM项目中,没有Spring Boot的自动配置机制,@WebFilter的生效依赖Servlet容器的扫描(比如Tomcat的自动扫描),但通常我们更习惯在web.xml里通过<filter>和<filter-mapping>标签配置过滤器,或者用Spring的@Bean来注册FilterRegistrationBean,和Spring Boot的自动扫描逻辑差异很大,所以不能直接套用Spring Boot的经验。

避坑提醒

别同时用@Component + @WebFilter + @ServletComponentScan!这会导致你的过滤器被注册两次——一次是Spring通过@Component注册,另一次是@ServletComponentScan扫描@WebFilter注册,最终过滤器的doFilter方法会被执行两次,引发不必要的问题。

备注:内容来源于stack exchange,提问作者Blaze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 13:39:35