DelegatingFilterProxy

简介: 在web.xml中配置的DelegatingFilterProxy,实际是Spring Security的入口。其核心是通过`doFilter`方法,首次调用时根据`targetBeanName`(即`springSecurityFilterChain`)从Spring容器中获取真正的过滤器`FilterChainProxy`,并缓存到`delegate`属性。随后执行该代理过滤器,实现安全控制链。

我们在web.xml中配置了一个名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对 DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码,大家注意我写的注释就行了!
public class DelegatingFilterProxy extends GenericFilterBean {
@Nullable
private String contextAttribute;
@Nullable
private WebApplicationContext webApplicationContext;
@Nullable
private String targetBeanName;
private boolean targetFilterLifecycle;
@Nullable
private volatile Filter delegate;//注:这个过滤器才是真正加载的过滤器
private final Object delegateMonitor;
//注:doFilter才是过滤器的入口,直接从这看!
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain
filterChain) throws ServletException, IOException {
Filter delegateToUse = this.delegate;
if (delegateToUse == null) {
synchronized(this.delegateMonitor) {
delegateToUse = this.delegate;
if (delegateToUse == null) {
WebApplicationContext wac = this.findWebApplicationContext();
if (wac == null) {
throw new IllegalStateException("No WebApplicationContext found: no
ContextLoaderListener or DispatcherServlet registered?");
}
//第一步:doFilter中最重要的一步,初始化上面私有过滤器属性delegate
delegateToUse = this.initDelegate(wac);
}
this.delegate = delegateToUse;
}
}
//第三步:执行FilterChainProxy过滤器
this.invokeDelegate(delegateToUse, request, response, filterChain);
}
//第二步:直接看最终加载的过滤器到底是谁
protected Filter initDelegate(WebApplicationContext wac) throws ServletException {
//debug得知targetBeanName为:springSecurityFilterChain
String targetBeanName = this.getTargetBeanName();
Assert.state(targetBeanName != null, "No target bean name set");
//debug得知delegate对象为:FilterChainProxy
Filter delegate = (Filter)wac.getBean(targetBeanName, Filter.class);
if (this.isTargetFilterLifecycle()) {
delegate.init(this.getFilterConfig());
}
return delegate;
}
}
第二步debug结果如下:

由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器, 最终在第三步执行了这个过滤器。

相关文章
|
Java 开发者 Spring
深入理解Spring Boot的@ComponentScan注解
【4月更文挑战第22天】在构建 Spring Boot 应用时,@ComponentScan 是一个不可或缺的工具,它使得组件发现变得自动化和高效。这篇博客将详细介绍 @ComponentScan 的基本概念、关键属性及其在实际开发中的应用。
1536 4
|
SQL 存储 关系型数据库
【面试题精讲】mysql-update语句执行流程
【面试题精讲】mysql-update语句执行流程
|
Arthas Java 测试技术
Docker 环境中 Spring Boot 应用的 Arthas 故障排查与性能优化实战
Docker 环境中 Spring Boot 应用的 Arthas 故障排查与性能优化实战
|
8月前
|
存储 弹性计算 人工智能
2026阿里云服务器租用价格与计费指南:新购、续费、升级活动报价全解析
阿里云服务器凭借弹性伸缩、安全可靠的特性,覆盖个人开发、企业业务及高性能计算等多场景需求。其产品体系主要包含轻量应用服务器、云服务器 ECS 及 GPU 服务器三类,不同机型在配置、定价及适用场景上各有侧重,同时通过差异化的计费模式与优惠政策,满足不同用户的成本控制需求。本文将从各类型服务器的配置规格、价格体系(年付、月付、按小时计费)、续费政策及附加资源(带宽、存储)定价展开详细说明,为用户提供清晰的成本参考。
|
9月前
|
JSON Java 数据格式
Spring Boot中的全局异常处理
本文介绍了Spring Boot项目中如何实现全局异常处理。通过@ControllerAdvice和@ExceptionHandler统一捕获系统异常与自定义业务异常,结合统一JSON返回结构,避免代码耦合,提升可维护性。同时利用枚举管理异常码,实现异常信息的集中管理和友好提示,适用于前后端分离及微服务架构,保障接口返回一致性,降低维护成本。
|
10月前
|
SQL 缓存 Java
【Java架构必看】Mybatis的工作原理
MyBatis执行分启动与运行两阶段:启动时加载配置,运行时代理执行SQL。通过JDK动态代理生成Mapper接口,结合缓存机制与Executor执行SQL,最终由TypeHandler完成结果映射。
585 4
|
Java Spring
SpringBoot入门(5) - 定制自己的Banner
SpringBoot入门(5) - 定制自己的Banner
815 0
 SpringBoot入门(5) - 定制自己的Banner
|
弹性计算 运维 安全
阿里云服务器通用算力型u1实例简单测评:性能、优势与最新价格参考
在阿里云2025年的活动中,独享型通用算力u1云服务器是用户比较关注的云服务器,因为它的性能要比活动内的经济型e实例好,但是价格又比计算型c8i、通用型g8i等其他企业级实例的价格要便宜。那么,独享型通用算力u1云服务器到底怎么样呢?它又有哪些优势呢?接下来,本文将为您详细解析。
|
Java API Spring
Java实现异步编程的几种方式
通过本文的介绍,我们了解了在Java中实现异步编程的几种常用方式。每种方法都有其优点和适用场景,具体选择哪种方式应根据实际需求和场景决定。如果任务较简单,可以使用 `Thread`或 `ExecutorService`;如果需要处理复杂的异步流程,可以考虑使用 `CompletableFuture`或Reactive编程框架。希望本文对您理解和实现Java异步编程有所帮助。
743 1