一、使用 @Component
+ @Order
(簡單但不夠靈活)
適用于全局過濾器,無需手動注冊,Spring Boot 會自動掃描并注冊。
@Component
@Order(1) // 數字越小,優先級越高
public class AuthFilter implements Filter {@Autowired // 依賴注入正常private AuthService authService;@Overridepublic 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 {@Overridepublic 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 {@Beanpublic 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 {@Beanpublic FilterRegistrationBean<MyFilter> myFilterRegistration(MyFilter myFilter) { // 注入 MyFilterFilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();registration.setFilter(myFilter); // 使用 Spring 管理的 Beanregistration.addUrlPatterns("/admin/*");registration.setOrder(1);return registration;}
}@Component // 必須加 @Component 或 @Service
public class MyFilter implements Filter {@Autowired // 現在可以正常注入private AdminService adminService;@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 使用 adminServicechain.doFilter(request, response);}
}
優點:
?? 依賴注入正常
?? 支持精確控制 URL 和順序
總結對比
注冊方式 | 依賴注入 | URL 匹配 | 順序控制 | 適用場景 |
---|---|---|---|---|
@Component + @Order | ? 支持 | ? 默認 /* | ? @Order | 全局過濾器 |
@WebFilter + @ServletComponentScan | ? 不支持 | ? 自定義 | ? @Order | 簡單 URL 過濾 |
FilterRegistrationBean (直接 new ) | ? 不支持 | ? 自定義 | ? setOrder() | ? 不推薦 |
FilterRegistrationBean (注入 Bean) | ? 支持 | ? 自定義 | ? setOrder() | ? 推薦方式 |
最佳實踐建議
- 優先使用
FilterRegistrationBean
+ 構造函數注入(解決方案1),兼顧靈活性和依賴注入。 - 如果只是全局過濾器,可以用
@Component
+@Order
。 - 避免直接
new Filter()
,否則@Autowired
會失效。