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

相关推荐
想摆烂的不会研究的研究生18 小时前
每日八股——Redis(1)
数据库·经验分享·redis·后端·缓存
毕设源码-郭学长18 小时前
【开题答辩全过程】以 基于SpringBoot技术的美妆销售系统为例,包含答辩的问题和答案
java·spring boot·后端
梨落秋霜18 小时前
Python入门篇【文件处理】
android·java·python
N***H48618 小时前
springcloud springboot nacos版本对应
spring boot·spring·spring cloud
Java 码农18 小时前
RabbitMQ集群部署方案及配置指南03
java·python·rabbitmq
哈库纳玛塔塔18 小时前
放弃 MyBatis,拥抱新一代 Java 数据访问库
java·开发语言·数据库·mybatis·orm·dbvisitor
追逐时光者19 小时前
精选 10 款 .NET 开源免费、功能强大的 Windows 效率软件
后端·.net
追逐时光者19 小时前
一款开源、免费的 WPF 自定义控件集
后端·.net
S***q37719 小时前
Spring Boot管理用户数据
java·spring boot·后端
天“码”行空20 小时前
java面向对象的三大特性之一多态
java·开发语言·jvm