在 Spring Boot 3.x 中,仅用 @Component 标记 Filter 类无法自动注册,必须通过 FilterRegistrationBean 显式配置 URL 拦截路径,否则 Filter 不会被容器调用。
在 spring boot 3.x 中,仅用 `@component` 标记 filter 类无法自动注册,必须通过 `filterregistrationbean` 显式配置 url 拦截路径,否则 filter 不会被容器调用。
Spring Boot 3.x(基于 Servlet 6.0+ 和 Jakarta EE 9+)对 Filter 的自动注册机制进行了严格限制:@Component 不再隐式注册 Filter。这是与 Spring Boot 2.x 的关键差异——后者在某些条件下可自动扫描并注册 @Component Filter,而 3.x 默认要求显式声明注册逻辑,以提升可预测性和安全性。
✅ 正确注册方式:使用 FilterRegistrationBean
需创建一个 @Configuration 类,并通过 @Bean 方法返回配置好的 FilterRegistrationBean:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.example.demo.filter.CustumRequestFilter;
@Configuration
public class FilterConfiguration {
@Bean
public FilterRegistrationBean<custumrequestfilter> customRequestFilterRegistration() {
FilterRegistrationBean<custumrequestfilter> registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new CustumRequestFilter());
registrationBean.addUrlPatterns("/*"); // 拦截所有请求(支持 "/api/*", "/admin/*" 等)
registrationBean.setOrder(1); // 可选:控制执行顺序,数值越小优先级越高
return registrationBean;
}
}</custumrequestfilter></custumrequestfilter>
⚠️ 注意:addUrlPatterns("/*") 是必需的;若不设置,Filter 将完全不参与请求链。
? 修复原始 Filter 中的代码问题
您原 Filter 中存在两处严重错误,会导致运行时异常:
-
类型强转错误:
((HttpServletResponse) request).setHeader(...) // ❌ request 是 HttpServletRequest,不能转为 HttpServletResponse
应改为:
res.setHeader("X-TEST-REQUEST", "FOOBAR-REQUEST"); // ✅ 使用已转换的 res req.getHeader("User-Agent"); // 示例:安全读取请求头 -
重复强转且逻辑错位:
((HttpServletResponse) response).setHeader(...) // ✅ 此行正确,但建议直接用 res
修正后的 doFilter 片段如下:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
System.out.println("[Filter] Intercepted: " + req.getRequestURI());
res.setHeader("X-TEST-REQUEST", "FOOBAR-REQUEST");
res.setHeader("X-TEST-RESPONSE", "FOOBAR-RESPONSE");
chain.doFilter(request, response); // ✅ 必须调用,否则请求中断
}
? 补充说明
- 不要在 Filter 中写响应体(如 response.getOutputStream().write(...)),除非明确要短路请求(即不调用 chain.doFilter())。否则易引发 IllegalStateException: getOutputStream() has already been called。
- 若需全局生效且路径复杂,可结合 setServletNames("default") 或指定 ServletRegistrationBean 名称。
- 推荐使用 jakarta.servlet.* 包(Spring Boot 3.x 强制要求),确保导入正确:
import jakarta.servlet.Filter;、jakarta.servlet.FilterChain; 等。
通过以上配置与修正,您的 CustumRequestFilter 即可被 Spring Boot 容器识别、注册并正常执行。










