这里的方法比较简单:
- getConfigurer 获取一个配置对象 。Spring Security 过滤器链中的所有过滤器对象都是由 xxxConfigure 来进行配置的,这里就是获取这个 xxxConfigure 对象 。
- removeConfigurer 移除一个配置对象 。
- setSharedObject/getSharedObject 配置/获取由多个 SecurityConfigurer 共享的对象 。
- authenticationProvider 方法表示配置验证器 。
- userDetailsService 配置数据源接口 。
- addFilterAfter 在某一个过滤器之前添加过滤器 。
- addFilterBefore 在某一个过滤器之后添加过滤器 。
- addFilter 添加一个过滤器,该过滤器必须是现有过滤器链中某一个过滤器或者其扩展 。
1.4 AbstractSecurityBuilderAbstractSecurityBuilder 类实现了 SecurityBuilder 接口,该类中主要做了一件事,就是确保整个构建只被构建一次 。
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> { private AtomicBoolean building = new AtomicBoolean(); private O object; public final O build() throws Exception { if (this.building.compareAndSet(false, true)) { this.object = doBuild(); return this.object; } throw new AlreadyBuiltException("This object has already been built"); } public final O getObject() { if (!this.building.get()) { throw new IllegalStateException("This object has not been built"); } return this.object; } protected abstract O doBuild() throws Exception;}
可以看到,这里重新定义了 build 方法,并设置 build 方法为 final 类型,无法被重写,在 build 方法中,通过 AtomicBoolean 实现该方法只被调用一次 。具体的构建逻辑则定义了新的抽象方法 doBuild,将来在实现类中通过 doBuild 方法定义构建逻辑 。1.5 AbstractConfiguredSecurityBuilderAbstractSecurityBuilder 方法的实现类就是 AbstractConfiguredSecurityBuilder 。
AbstractConfiguredSecurityBuilder 中所做的事情就比较多了,我们分别来看 。
首先 AbstractConfiguredSecurityBuilder 中定义了一个枚举类,将整个构建过程分为 5 种状态,也可以理解为构建过程生命周期的五个阶段,如下:
private enum BuildState { UNBUILT(0), INITIALIZING(1), CONFIGURING(2), BUILDING(3), BUILT(4); private final int order; BuildState(int order) { this.order = order; } public boolean isInitializing() { return INITIALIZING.order == order; } public boolean isConfigured() { return order >= CONFIGURING.order; }}
五种状态分别是 UNBUILT、INITIALIZING、CONFIGURING、BUILDING 以及 BUILT 。另外还提供了两个判断方法,isInitializing 判断是否正在初始化,isConfigured 表示是否已经配置完毕 。AbstractConfiguredSecurityBuilder 中的方法比较多,松哥在这里列出来两个关键的方法和大家分析:
private <C extends SecurityConfigurer<O, B>> void add(C configurer) { Assert.notNull(configurer, "configurer cannot be null"); Class<? extends SecurityConfigurer<O, B>> clazz = (Class<? extends SecurityConfigurer<O, B>>) configurer .getClass(); synchronized (configurers) { if (buildState.isConfigured()) { throw new IllegalStateException("Cannot Apply " + configurer + " to already built object"); } List<SecurityConfigurer<O, B>> configs = allowConfigurersOfSameType ? this.configurers .get(clazz) : null; if (configs == null) { configs = new ArrayList<>(1); } configs.add(configurer); this.configurers.put(clazz, configs); if (buildState.isInitializing()) { this.configurersAddedInInitializing.add(configurer); } }}private Collection<SecurityConfigurer<O, B>> getConfigurers() { List<SecurityConfigurer<O, B>> result = new ArrayList<>(); for (List<SecurityConfigurer<O, B>> configs : this.configurers.values()) { result.addAll(configs); } return result;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 虞美人陈与义阅读理解
- 邦威古茶树你理解没,过渡性茶树
- 什么是MQ?什么是RabbitMQ?能做什么?简单理解一下?
- 网站安全维护SQL攻击防护方案
- 如何理解周礼一书中体现的内部控制制度 中国古代组织管理思想也许起源于周礼
- 资深架构师:深入聊聊获取屏幕高度这件事
- 轻松理解机器学习算法:Adaboost算法
- 并发编程之定时任务&定时线程池原理解析
- 图解Raft:应该是最容易理解的分布式一致性算法
- 无锁队列Disruptor原理解析