DelegatingFilterProxyRegistrationBean
是Spring Boot
提供的针对Servlet 3.0+ Web
的一个注册器Bean
(RegistrationBean
)。它的作用是向Servlet
容器注册一个Servlet Filter
,实现类为DelegatingFilterProxy
。该Filter DelegatingFilterProxy
虽然实现了Filter
接口,但它其实只是一个代理,DelegatingFilterProxyRegistrationBean
为其指定了Spring IoC
容器中另外一个Filter bean
作为被代理的Filter bean
。最终Servlet
容器调用该Filter DelegatingFilterProxy
时,其实最终任务执行落在被代理的那个Filter bean
上。
DelegatingFilterProxyRegistrationBean
继承自AbstractFilterRegistrationBean
。基类AbstractFilterRegistrationBean
定义了向Servlet
容器注册并配置一个Filter
的通用逻辑,其子实现类负责将要被注册到Servlet
容器的Filter
的提供。DelegatingFilterProxyRegistrationBean
正是这样一个子类,它提供的Filter
是基于指定名称构建的一个DelegatingFilterProxy Filter
。跟DelegatingFilterProxyRegistrationBean
类似的另外一个注册器Bean
是FilterRegistrationBean
。FilterRegistrationBean
也继承自AbstractFilterRegistrationBean
,但不同的是,FilterRegistrationBean
向Servlet
容器注册的是某个Filter
对象自身,而不是一个代理Filter
对象。
基于DelegatingFilterProxyRegistrationBean
及其基类AbstractFilterRegistrationBean
所定义的能力,可以做到以下几点 :
- 向
Servlet
容器注册一个DelegatingFilterProxy Filter
用于代理Spring IoC
容器中某个指定名称的Filter bean
; - 可以指定被代理的
Filter bean
应用到哪些URL
路径上(通过#setUrlPatterns
); - 可以指定被代理的
Filter bean
应用到那些Servlet
上(通过#setServletNames
或者#setServletRegistrationBeans
); - 如果没有指定被代理的
Filter bean
应用到哪些URL/Servlet
上,则缺省应用到/*
上。
DelegatingFilterProxyRegistrationBean
的使用可以参考SecurityFilterAutoConfiguration
,这是Spring Boot
针对Servlet Web
的一个自动配置类。它的作用就是在其他基础安全自动配置(SecurityAutoConfiguration
)结束之后,向Spring IoC
容器注册一个DelegatingFilterProxyRegistrationBean
。而随后DelegatingFilterProxyRegistrationBean
会在Servlet
容器启动阶段被用于注册相应的DelegatingFilterProxy
代理Filter
。
源代码
源代码版本 : Spring Boot 2.1.3.RELEASE
package org.springframework.boot.web.servlet;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
public class DelegatingFilterProxyRegistrationBean
extends AbstractFilterRegistrationBean<DelegatingFilterProxy>
implements ApplicationContextAware {
private ApplicationContext applicationContext;
private final String targetBeanName;
/**
* Create a new DelegatingFilterProxyRegistrationBean instance to be
* registered with the specified ServletRegistrationBeans.
* @param targetBeanName name of the target filter bean to look up in the Spring
* application context (must not be null). 被代理的Filter bean的名称,必须不能是null
* @param servletRegistrationBeans associate ServletRegistrationBeans
*/
public DelegatingFilterProxyRegistrationBean(String targetBeanName,
ServletRegistrationBean<?>... servletRegistrationBeans) {
super(servletRegistrationBeans);
Assert.hasLength(targetBeanName, "TargetBeanName must not be null or empty");
this.targetBeanName = targetBeanName;
setName(targetBeanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
protected String getTargetBeanName() {
return this.targetBeanName;
}
// 构建要注册到Servlet容器的Filter,总是一个 DelegatingFilterProxy,代理到
// 名称为 targetBeanName 的目标 Filter bean
@Override
public DelegatingFilterProxy getFilter() {
return new DelegatingFilterProxy(this.targetBeanName,
getWebApplicationContext()) {
@Override
protected void initFilterBean() throws ServletException {
// Don't initialize filter bean on init()
}
};
}
private WebApplicationContext getWebApplicationContext() {
Assert.notNull(this.applicationContext, "ApplicationContext be injected");
Assert.isInstanceOf(WebApplicationContext.class, this.applicationContext);
return (WebApplicationContext) this.applicationContext;
}
}
参考资料
Spring Boot Web Servlet : AbstractFilterRegistrationBean
Spring Boot 自动配置 : SecurityAutoConfiguration
Springboot 自动配置 : SecurityFilterAutoConfiguration
Spring Web : DelegatingFilterProxy