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

相关推荐
ss2736 小时前
线程池优雅关闭:线程池生命周期管理:四种关闭策略的实战对比
java·jvm·算法
不能只会打代码6 小时前
蓝桥杯--生命之树(Java)
java·算法·蓝桥杯·动态规划·贪心
多则惑少则明6 小时前
AI大模型实用(九)Java快速实现智能体整理(使用LangChain4j-agentic + Tool)
java·人工智能·springai·langchain4j
与遨游于天地6 小时前
深入了解 Java `synchronized`:从对象头到锁升级、线程竞争感知
java·开发语言·c#
天天摸鱼的java工程师6 小时前
Kafka 消息积压处理实战:百万级队列清空的优化技巧
java·后端
东东的脑洞6 小时前
【面试突击四】JAVA基础知识-线程池与参数调优
java·面试
小股虫6 小时前
Tair Java实操手册:从零开始的缓存中间件入门指南
java·缓存·中间件
seekCat6 小时前
WPF中的IValueConverter接口(值转换器)
后端
Wyy_9527*6 小时前
Spring三种注入方式对比
java·后端·spring
一个大专生的淘汰之路6 小时前
Elasticsearch 中的 term的查询
后端