Springboot注册过滤器的三种方式(Order 排序)

发布于:2025-08-13 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、使用 @Component + @Order(简单但不够灵活)

适用于全局过滤器,无需手动注册,Spring Boot 会自动扫描并注册。

@Component
@Order(1)  // 数字越小,优先级越高
public class AuthFilter implements Filter {
    
    @Autowired  // 依赖注入正常
    private AuthService authService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        // 认证逻辑
        chain.doFilter(request, response);
    }
}

特点:
✅ 简单,无需额外配置
✅ 支持 @Autowired 依赖注入
默认拦截所有请求(/*),无法自定义 URL 匹配规则
❌ 多个过滤器时,@Order 顺序可能不够直观


二、使用 @WebFilter + @ServletComponentScan

适用于需要指定 URL 匹配规则的过滤器,但仍依赖 @Order 控制顺序。

@WebFilter(urlPatterns = "/api/*")  // 仅拦截 /api/*
@Order(2)  // 设置顺序
public class LoggingFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("请求进入 LoggingFilter");
        chain.doFilter(request, response);
    }
}

启动类需添加 @ServletComponentScan

@SpringBootApplication
@ServletComponentScan  // 扫描 @WebFilter
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

特点:
✅ 可自定义 URL 匹配规则
不支持 @Autowired 依赖注入(因为 @WebFilter 由 Servlet 容器管理,而非 Spring)
❌ 顺序控制仍依赖 @Order


三、 使用 FilterRegistrationBean(最灵活,推荐方式)

适用于需要精确控制 URL 匹配和顺序的场景,但需注意依赖注入问题。

@Configuration
public class FilterConfig {
    
    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistration() {
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new MyFilter());  // ⚠️问题:直接 new 导致依赖注入失效
        registration.addUrlPatterns("/admin/*");
        registration.setOrder(1);  // 明确指定顺序
        return registration;
    }
}

问题:
MyFilter 中的 @Autowired 依赖全部为 null

原因:
new MyFilter() 创建的实例不受 Spring 容器管理,导致 @Autowired 失效。


解决 FilterRegistrationBean 依赖注入问题

通过构造函数注入 Filter 实例:让 Spring 管理 MyFilter 的实例,再传给 FilterRegistrationBean

@Configuration
public class FilterConfig {
    
    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistration(MyFilter myFilter) {  // 注入 MyFilter
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(myFilter);  // 使用 Spring 管理的 Bean
        registration.addUrlPatterns("/admin/*");
        registration.setOrder(1);
        return registration;
    }
}

@Component  // 必须加 @Component 或 @Service
public class MyFilter implements Filter {
    
    @Autowired  // 现在可以正常注入
    private AdminService adminService;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        // 使用 adminService
        chain.doFilter(request, response);
    }
}

优点:
✔️ 依赖注入正常
✔️ 支持精确控制 URL 和顺序


总结对比

注册方式 依赖注入 URL 匹配 顺序控制 适用场景
@Component + @Order ✅ 支持 ❌ 默认 /* @Order 全局过滤器
@WebFilter + @ServletComponentScan ❌ 不支持 ✅ 自定义 @Order 简单 URL 过滤
FilterRegistrationBean(直接 new ❌ 不支持 ✅ 自定义 setOrder() ❌ 不推荐
FilterRegistrationBean(注入 Bean) ✅ 支持 ✅ 自定义 setOrder() ✅ 推荐方式

最佳实践建议

  1. 优先使用 FilterRegistrationBean + 构造函数注入(解决方案1),兼顾灵活性和依赖注入。
  2. 如果只是全局过滤器,可以用 @Component + @Order
  3. 避免直接 new Filter(),否则 @Autowired 会失效。

网站公告

今日签到

点亮在社区的每一天
去签到