Spring Security源码学习——建造者基础架构

前言

Spring Security整个框架的核心就是构建一个名字为 springSecurityFilterChain 的过滤器Bean,它的类型是 FilterChainProxy

它整个框架主要由 建造者 和 配置器 构成,在服务启动时就是 通过配置器对建造者进行配置 ,配置完成再由建造者创建出核心过滤器。

本文主要讲的就是他的建造者

1、SecurityBuilder
public interface SecurityBuilder<O> {
	O build() throws Exception;
}

其类继承结构图如下
在这里插入图片描述

基本实现是AbstractConfiguredSecurityBuilder及其子类AbstractConfiguredSecurityBuilder。

WebSecurity构建目标是整个Spring Security安全过滤器FilterChainProxy,
HttpSecurity的构建目标仅仅是FilterChainProxy中的一个SecurityFilterChain。
AuthenticationManagerBuilder的作用是构建AuthenticationManager

2、AbstractSecurityBuilder

说明:SecurityBuilder的抽象子类,确保建造者只被构建一次,对父接口方法 build() 进行了原子判断,保证每次只构建一次,定义了一个抽象方法 doBuild() 供子类扩展

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;
}
2、AbstractConfiguredSecurityBuilder
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
		extends AbstractSecurityBuilder<O> {
	
	/// 所要应用到当前 SecurityBuilder 上的所有的 SecurityConfigurer
	private final LinkedHashMap<Class<? extends SecurityConfigurer<O, B>>, List<SecurityConfigurer<O, B>>> configurers = new LinkedHashMap<>();
	
	//  用于记录在初始化期间添加进来的 SecurityConfigurer
	private final List<SecurityConfigurer<O, B>> configurersAddedInInitializing = new ArrayList<>();

   // 共享对象
	private final Map<Class<?>, Object> sharedObjects = new HashMap<>();

	private final boolean allowConfigurersOfSameType;

	private BuildState buildState = BuildState.UNBUILT;

	private ObjectPostProcessor<Object> objectPostProcessor;


	//允许配置器应用到建造者中,实际上就是把各种配置添加到该类定义的配置器列表 configurers、configurersAddedInInitializing
	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);
			}
		}
	}





	//实现的父类方法,真正执行构建的方法,方法中调用了 init()、configure()
	protected final O doBuild() throws Exception {
		synchronized (configurers) {
			buildState = BuildState.INITIALIZING;

			beforeInit();
			init();

			buildState = BuildState.CONFIGURING;

			beforeConfigure();
			configure();

			buildState = BuildState.BUILDING;

			O result = performBuild();

			buildState = BuildState.BUILT;

			return result;
		}
	}


	protected void beforeInit() throws Exception {
	}

	
	protected void beforeConfigure() throws Exception {
	}

	//配置完所有之后,进行实际的执行,该方法是抽象方法,留给下层子类(WebSecurity、HttpSecurity) 实现
	protected abstract O performBuild() throws Exception;

	//循环初始化所有的 configurers、configurersAddedInInitializing 配置
	private void init() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.init((B) this);
		}

		for (SecurityConfigurer<O, B> configurer : configurersAddedInInitializing) {
			configurer.init((B) this);
		}
	}

	//循环配置所有的 configurers
	private void configure() throws Exception {
		Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

		for (SecurityConfigurer<O, B> configurer : configurers) {
			configurer.configure((B) this);
		}
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值