过滤器链加载原理

简介: 通过前文介绍的十五个过滤器,我们了解了Spring Security的工作流程。本文深入源码,解析DelegatingFilterProxy如何加载springSecurityFilterChain,进而引出FilterChainProxy与SecurityFilterChain的实现机制,揭示过滤器链自动装配原理,为自定义认证页面奠定基础。(238字)

通过前面十五个过滤器功能的介绍,对于SpringSecurity简单入门中的疑惑是不是在心中已经有了答案了呀? 但新的问题来了!我们并没有配置这些过滤器啊?它们都是怎么被加载出来的?
1-DelegatingFilterProxy
我们在web.xml中配置了一个名称为springSecurityFilterChain的过滤器DelegatingFilterProxy,接下我直接对 DelegatingFilterProxy源码里重要代码进行说明,其中删减掉了一些不重要的代码,大家注意我写的注释就行了!
第二步debug结果如下:

由此可知,DelegatingFilterProxy通过springSecurityFilterChain这个名称,得到了一个FilterChainProxy过滤器, 最终在第三步执行了这个过滤器。
2-FilterChainProxy
注意代码注释!
第二步debug结果如下图所示,惊不惊喜?十五个过滤器都在这里了!
再看第三步,怀疑这么久!原来这些过滤器还真是都被封装进SecurityFilterChain中了。
3-SecurityFilterChain
最后看SecurityFilterChain,这是个接口,实现类也只有一个,这才是web.xml中配置的过滤器链对象!
Java
运行代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//接口
public interface SecurityFilterChain {
boolean matches(HttpServletRequest var1);
List getFilters();
}

//实现类
public final class DefaultSecurityFilterChain implements SecurityFilterChain {

private static final Log logger = LogFactory.getLog(DefaultSecurityFilterChain.class);
private final RequestMatcher requestMatcher;
private final List<Filter> filters;

public DefaultSecurityFilterChain(RequestMatcher requestMatcher,
                                  Filter... filters) {
    this(requestMatcher, Arrays.asList(filters));
}

public DefaultSecurityFilterChain(RequestMatcher requestMatcher, 
                                  List<Filter> filters) {
    logger.info("Creating filter chain: " + requestMatcher + ", " + filters);
    this.requestMatcher = requestMatcher;
    this.filters = new ArrayList(filters);
}

public RequestMatcher getRequestMatcher() {
    return this.requestMatcher;
}

public List<Filter> getFilters() {
    return this.filters;
}

public boolean matches(HttpServletRequest request) {
    return this.requestMatcher.matches(request);
}

public String toString() {
    return "[ " + this.requestMatcher + ", " + this.filters + "]";
}

}
总结:通过此章节,我们对SpringSecurity工作原理有了一定的认识。但理论千万条,功能第一条,探寻底层,是为了更好的使用框架。 那么,言归正传!到底如何使用自己的页面来实现SpringSecurity的认证操作呢?要完成此功能,首先要有一套自己的页面!

相关文章
|
2月前
|
消息中间件 存储 缓存
MQ篇
本项目采用RabbitMQ、Kafka和EMQ实现异步通信与数据采集。RabbitMQ用于服务解耦、流量削峰,支持多种消息模式与高可用集群;Kafka处理高吞吐用户行为数据,保障实时推荐与数据同步;EMQ基于MQTT协议实现物联网设备与服务器间可靠通信,支持QoS分级与延迟发布,确保消息不丢不重。三者协同提升系统性能与稳定性。
|
2月前
|
负载均衡 算法 Java
微服务篇
SpringBoot核心原理是自动装配,通过@SpringBootApplication注解实现配置类、组件扫描与自动配置。其启动流程包括环境初始化、上下文创建与自动化配置。常用起步依赖如web、redis等;支持properties、YAML等配置文件,后加载的覆盖先加载的。项目通过Feign、Ribbon实现服务通信与负载均衡,使用Nacos做注册与配置中心,Sentinel或Hystrix实现限流熔断,Gateway实现网关限流与CORS跨域控制,结合Spring Cloud五大组件构建微服务架构。
|
2月前
|
数据可视化 数据挖掘 BI
性能优化专题
两幅图像展示了数据可视化图表,包含柱状图与折线图的组合,呈现清晰的趋势分析与对比数据,适用于业务报表、数据分析等场景,助力直观理解关键指标变化。
|
2月前
|
人工智能 NoSQL Java
幂等方案专题
xxx智能教育辅导平台基于Spring Cloud Alibaba构建,融合大模型与知识图谱技术,实现学情诊断、自适应学习与智能批改。通过通义千问Max分析作业数据,精准定位知识盲区;结合Neo4j构建学科能力网络,动态推荐个性化学习路径;集成OCR与语义理解实现作文智能批改,准确率超98%。支持高并发访问,日均处理50万+作业请求,提升教学效率与学习体验。
|
2月前
|
存储 关系型数据库 MySQL
事务控制篇
关系型数据库基于表结构,支持事务与复杂查询,适用于强一致性场景;非关系型数据库灵活高效,适合高并发、海量数据场景。索引提升查询速度,常用B+树实现,因遍历、IO性能更优。MySQL通过redo log、undo log保障ACID,利用分库分表、读写分离应对高并发。
|
2月前
|
存储 缓存 NoSQL
Redis篇
本项目中Redis广泛应用于缓存、数据存储与分布式锁。用于缓存热点数据、用户信息及计算结果,提升系统性能;通过哨兵集群实现高可用,结合LFU策略保障热点数据留存;利用布隆过滤器、空值缓存等应对缓存穿透,配合MQ与TCC保证Redis与MySQL数据一致性,并在任务调度中实现分布式锁避免重复执行。
|
2月前
|
存储 SQL 关系型数据库
MySQL篇
MySQL查询语句书写顺序为:SELECT、FROM、JOIN、WHERE、GROUP BY、HAVING、ORDER BY、LIMIT;实际执行顺序则不同,从FROM开始,最后执行SELECT和LIMIT。多表查询主要通过内连接(显式/隐式)和外连接(左、右)实现。内连接仅返回匹配行,外连接保留驱动表全部记录。CHAR固定长度,VARCHAR可变长度;索引类型包括单列、组合及全文索引,底层多用B+树结构。InnoDB使用聚簇索引,数据存于主键索引叶节点;MyISAM为非聚簇索引,叶节点存指针。查询非主键索引需回表二次查找,覆盖索引可避免回表提升性能。
|
2月前
|
存储 缓存 安全
Java基础篇
本文简要介绍了Java核心知识,涵盖final关键字、重载与重写、==与equals区别、反射机制及应用、String类对比、集合框架、线程安全类、ArrayList与LinkedList差异、HashMap原理及扩容、ConcurrentHashMap实现、线程创建与线程池使用、JVM组成与运行时数据区、类加载器与双亲委派模型、Stream流及JDK8新特性等内容,系统梳理了Java开发中的重点概念与实战应用。
|
2月前
|
安全 Java 数据安全/隐私保护
通用权限管理模型
本文介绍ACL与RBAC两大核心权限模型。ACL通过用户/角色直接授权,简单直观;RBAC则基于角色分配权限,支持角色继承、职责分离等机制,更适用于复杂系统。了解模型结构有助于构建清晰的权限体系。
|
2月前
|
缓存 开发工具 git
QLExpress使用及源码分析
QLExpress是阿里开源的轻量级规则引擎,支持通过注解与YAML配置实现业务逻辑与代码解耦。结合实体别名、接口规则定义及脚本化表达式,实现动态计算与判断,如用户年龄判断、BMI计算等。支持AST语法树解析与上下文绑定,提供灵活的二次扩展能力,适用于复杂业务场景的延迟执行与缓存优化。