这段配置是 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 的工作流程如下:
- 客户端发送请求到应用,Servlet 容器(如 Tomcat)首先触发
DelegatingFilterProxy的doFilter()方法。 DelegatingFilterProxy从 Spring 容器中查找目标过滤器 Bean :- 默认情况下,目标 Bean 的名称与
<filter-name>一致(即myFilter)。 - 若需指定其他名称,可通过
init-param增加<param-name>targetBeanName</param-name><param-value>实际Bean名称</param-value>。
- 默认情况下,目标 Bean 的名称与
- 将请求委托给目标过滤器的
doFilter()方法,由目标过滤器处理实际业务逻辑(如权限校验、日志记录、跨域处理等)。 - 处理完成后,响应经过滤器返回给客户端。
为什么需要这种配置?
传统的 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委托给springSecurityFilterChainBean,实现安全校验。 - 自定义过滤器:需要依赖注入的业务过滤器(如令牌验证、日志收集等)。
总结
这段配置的作用是:注册一个 Spring 代理过滤器 myFilter,通过 DelegatingFilterProxy 将所有客户端直接请求(/* + REQUEST)委托给 Spring 容器中名为 myFilter 的目标过滤器 Bean 处理,同时确保目标过滤器的生命周期方法(init()、destroy())能正常执行。
它是 Spring 整合 Web 过滤器的标准方式,解决了过滤器依赖注入的问题,让过滤器能充分利用 Spring 的特性。