Spring 的 DelegatingFilterProxy 用法

这段配置是 Spring 框架中使用 org.springframework.web.filter.DelegatingFilterProxy(Spring 原生的代理过滤器)的标准 XML 配置,核心作用是将 Servlet 容器的过滤器机制与 Spring 容器管理的 Bean 关联起来,让过滤器能够利用 Spring 的依赖注入、AOP 等特性。以下是详细解析:

1. <filter> 标签:定义 Spring 代理过滤器

xml 复制代码
<filter>
    <filter-name>myFilter</filter-name>  <!-- 过滤器的唯一标识名称 -->
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  <!-- Spring 原生代理过滤器 -->
    <init-param>  <!-- 初始化参数 -->
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
  • <filter-name> :给过滤器命名(myFilter),用于后续的映射配置,名称需唯一。

  • <filter-class> :指定过滤器实现类为 Spring 提供的 DelegatingFilterProxy

    这个类的核心功能是**"代理":它自身不处理具体的过滤逻辑,而是将请求 委托给 Spring 容器中一个真正的过滤器 Bean**(目标 Bean)。

    这样做的目的是:让目标过滤器能被 Spring 容器管理(例如通过 @Component 注册),从而可以注入 Spring 中的其他 Bean(如 Service、Repository 等),解决了传统 Servlet 过滤器无法依赖注入的问题。

  • <init-param>targetFilterLifecycle=true 是关键配置:

    • 当值为 false(默认)时,DelegatingFilterProxy 仅将 doFilter() 方法委托给目标 Bean,而过滤器的生命周期方法(init()destroy())不会委托(由 DelegatingFilterProxy 自身处理)。
    • 当值为 true 时,DelegatingFilterProxy 会将 init()destroy() 也委托给目标 Bean,确保目标过滤器的初始化(如加载配置)和销毁(如释放资源)逻辑能正常执行。

2. <filter-mapping> 标签:定义过滤器的拦截规则

xml 复制代码
<filter-mapping>
    <filter-name>myFilter</filter-name>  <!-- 关联前面定义的过滤器名称 -->
    <url-pattern>/*</url-pattern>  <!-- 拦截所有请求 -->
    <dispatcher>REQUEST</dispatcher>  <!-- 拦截直接来自客户端的请求 -->
</filter-mapping>
  • <filter-name> :关联到前面定义的 myFilter,表示当前映射规则应用于该过滤器。

  • <url-pattern>/*</url-pattern> :指定过滤器拦截的 URL 路径。/* 表示拦截应用中所有请求(包括接口请求、静态资源如 CSS/JS、HTML 页面等)。其他常见模式如:

    • /api/*:仅拦截 /api 路径下的请求;
    • *.do:仅拦截以 .do 结尾的请求。
  • <dispatcher>REQUEST</dispatcher> :指定拦截的请求类型。REQUEST 表示只拦截客户端直接发送的 HTTP 请求(如浏览器输入 URL、AJAX 调用等)。其他可选值包括:

    • FORWARD:拦截通过 request.getRequestDispatcher().forward() 转发的请求;
    • INCLUDE:拦截通过 request.getRequestDispatcher().include() 包含的请求;
    • ERROR:拦截处理错误页面的请求(如 web.xml 中配置的 <error-page>);
    • ASYNC:拦截异步请求(Servlet 3.0+ 支持)。

核心工作原理:代理与委托

DelegatingFilterProxy 的工作流程如下:

  1. 客户端发送请求到应用,Servlet 容器(如 Tomcat)首先触发 DelegatingFilterProxydoFilter() 方法。
  2. DelegatingFilterProxy 从 Spring 容器中查找目标过滤器 Bean
    • 默认情况下,目标 Bean 的名称与 <filter-name> 一致(即 myFilter)。
    • 若需指定其他名称,可通过 init-param 增加 <param-name>targetBeanName</param-name><param-value>实际Bean名称</param-value>
  3. 将请求委托给目标过滤器的 doFilter() 方法,由目标过滤器处理实际业务逻辑(如权限校验、日志记录、跨域处理等)。
  4. 处理完成后,响应经过滤器返回给客户端。

为什么需要这种配置?

传统的 Servlet 过滤器由 Servlet 容器(而非 Spring)管理,无法直接使用 Spring 的依赖注入(例如在过滤器中注入 @Autowired 的 Service)。而 DelegatingFilterProxy 作为"桥梁",让过滤器的实例由 Spring 容器管理,从而实现了过滤器与 Spring 生态的无缝集成。

例如,目标过滤器可以是一个 Spring 组件:

java 复制代码
@Component("myFilter") // Bean名称与<filter-name>一致,被DelegatingFilterProxy委托
public class MyActualFilter implements Filter {
    @Autowired
    private UserService userService; // 可以直接注入Spring管理的Bean

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        // 实际过滤逻辑,可使用userService处理业务
        chain.doFilter(request, response); // 放行请求
    }
}

典型应用场景

这种配置广泛用于需要 Spring 支持的过滤器场景,例如:

  • Spring Security:通过 DelegatingFilterProxy 委托给 springSecurityFilterChain Bean,实现安全校验。
  • 自定义过滤器:需要依赖注入的业务过滤器(如令牌验证、日志收集等)。

总结

这段配置的作用是:注册一个 Spring 代理过滤器 myFilter,通过 DelegatingFilterProxy 将所有客户端直接请求(/* + REQUEST)委托给 Spring 容器中名为 myFilter 的目标过滤器 Bean 处理,同时确保目标过滤器的生命周期方法(init()destroy())能正常执行

它是 Spring 整合 Web 过滤器的标准方式,解决了过滤器依赖注入的问题,让过滤器能充分利用 Spring 的特性。

相关推荐
tryxr2 小时前
Java 不同创建线程的方式什么时候才可以使用 this 来获取线程的引用
java·开发语言·多线程
代码程序猿RIP2 小时前
【C 语言面试】高频考点深度解析
java·面试·职场和发展
CodeSheep2 小时前
稚晖君公司的最新工资和招人标准
前端·后端·程序员
ashane13142 小时前
Springboot 启动过程及源码分析
java·spring boot·后端
caron42 小时前
c++ -- 循环依赖解决方案
java·c++·算法
不会kao代码的小王2 小时前
零基础也能搭博客?
linux·windows·后端
七夜zippoe2 小时前
深入理解Java泛型:类型擦除、通配符PECS原则与实践
java·泛型·通配符·类型擦除·pecs
程序员爱钓鱼2 小时前
Python编程实战 - Python实用工具与库 - 爬虫防封与代理机制
后端·python·ipython
程序员爱钓鱼2 小时前
Python编程实战 - Python实用工具与库 - 操作Excel:openpyxl / pandas
后端·python·面试