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 的特性。

相关推荐
v***91301 小时前
Spring boot创建时常用的依赖
java·spring boot·后端
代码or搬砖4 小时前
MyBatisPlus讲解(二)
java·mybatis
Cosolar4 小时前
银河麒麟 / aarch64 系统:Docker + Docker Compose 完整安装教程
后端·程序员·架构
星释4 小时前
Rust 练习册 100:音乐音阶生成器
开发语言·后端·rust
kaliarch4 小时前
2025年IaC生态全景与实践指南:从工具选型到多云治理
后端·云计算·自动化运维
lcu1114 小时前
Java 学习42:抽象
java
Mr.朱鹏4 小时前
RocketMQ安装与部署指南
java·数据库·spring·oracle·maven·rocketmq·seata
雨中飘荡的记忆4 小时前
Spring表达式详解:SpEL从入门到实战
java·spring
Coder-coco4 小时前
个人健康管理|基于springboot+vue+个人健康管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·mysql·论文
b***65324 小时前
springboot整合mybatis-plus(保姆教学) 及搭建项目
spring boot·后端·mybatis