目錄
1.構建過程
AbstractSecurityBuilder
AbstractConfiguredSecurityBuilder
WebSecurity
2.建造者類圖
SecurityBuilder
???????AbstractSecurityBuilder
???????AbstractConfiguredSecurityBuilder
???????WebSecurity
3.小結
? ? ? ? 緊接上一篇文章,這一篇我們來看看構建者WebSecurity是如何構建出一個過濾器對象springSecurityFilterChain的。
1.構建過程
? ? ? ? 點擊類WebSecurityConfiguration的方法springSecurityFilterChain()里的this.webSecurity.build(),如下所示:
AbstractSecurityBuilder
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
... ...
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");
}
? ? ? ? 在這里,build()方法調用了doBuild()方法。
? ? ? ? 點擊doBuild()方法,如下所示:
???????AbstractConfiguredSecurityBuilder
@Override
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;
???}
}
? ? ? ? 在這里,定義了構建對象的所有步驟。包括beforeInit、init、beforeConfigure、configure、performBuild的5個步驟。
? ? ? ? 點擊最后一步performBuild,如下所示:
???????WebSecurity
public final class WebSecurity extends
??????AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
??????SecurityBuilder<Filter>, ApplicationContextAware {... ...
@Override
protected Filter performBuild() throws Exception {
???int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
???List<SecurityFilterChain> securityFilterChains = new ArrayList<SecurityFilterChain>(
?????????chainSize);
???for (RequestMatcher ignoredRequest : ignoredRequests) {
??????securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
???}
???for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
??????securityFilterChains.add(securityFilterChainBuilder.build());
???}
???FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
???if (httpFirewall != null) {
??????filterChainProxy.setFirewall(httpFirewall);
???}
???filterChainProxy.afterPropertiesSet();
???Filter result = filterChainProxy;
???if (debugEnabled) {
??????result = new DebugFilter(filterChainProxy);
???}
???postBuildAction.run();
???return result;
}
? ? ? ? 在這里,可以看到構建的過濾器類是FilterChainProxy。至于這個類的具體結構,我們后續再進行深入的探究。
? ? ? ? 我們先看看在系統運行時,這個FilterChainProxy內部都包含有哪些Filter。
? ? ? ? 設置斷點,如下所示:
???????過濾器代理
? ? ? ? 在這里,我們看到了FilterChainProxy對象內部包含了很多的Filter。后續再深入了解這些Filter的配置過程及應用場景。
? ? ? ? 接下來我們重點學習一下與WebSecurity構建者相關的類圖模型。
2.建造者類圖
? ? ? ?在這里,AbstractSecurityBuilder、AbstractConfiguredSecurityBuilder、WebSecurity都是我們在上面一節中有接觸過的類。
???????SecurityBuilder
? ? ? ? 這個接口是建造者模式的頂級接口,含有建造者對外暴露的構建對象的一個接口方法?build()?。
? ? ? ? 代碼如下:
public interface SecurityBuilder<O> {
???O build() throws Exception;
}
???????AbstractSecurityBuilder
? ? ? ? 這個類是SecurityBuilder接口的抽象子類,實現了接口的build()方法,為確保構建對象只被構建一次,對父接口方法?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;
}
???????AbstractConfiguredSecurityBuilder
? ? ? ? 實現父類的doBuild()方法,這里是真正執行構建的地方。
? ? ? ? 首先,使用了建造者模式定義了構建對象的所有步驟;
? ? ? ? 其次,使用了模板方法模式,將構建對象的一些步驟延遲到子類中,使得子類可以不改變該算法結構的情況下重定義該算法的某些特定步驟。
? ? ? ? 代碼如下:
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>extends AbstractSecurityBuilder<O> {... ...public <C extends SecurityConfigurer<O, B>> C apply(C configurer) throws Exception {add(configurer);return configurer;}@SuppressWarnings("unchecked")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);}}}@Overrideprotected 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 {}protected abstract O performBuild() throws Exception;@SuppressWarnings("unchecked")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);}}@SuppressWarnings("unchecked")private void configure() throws Exception {Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();for (SecurityConfigurer<O, B> configurer : configurers) {configurer.configure((B) this);}}
}
???????WebSecurity
? ? ? ? 實現父類的?performBuild()方法,這是構建對象的所有步驟的最后一個步。通過實現父類方法的方式來定義具體的執行內容。
? ? ? ? WebSecurity?的目標是構建?FilterChainProxy?對象,即構建核心過濾器?springSecurityFilterChain。
? ? ? ? 代碼如下:
public final class WebSecurity extends
??????AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
??????SecurityBuilder<Filter>, ApplicationContextAware {
??????... ...
???@Override
???protected Filter performBuild() throws Exception {
??????int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
??????List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
????????????chainSize);
??????for (RequestMatcher ignoredRequest : ignoredRequests) {
?????????securityFilterChains.add(new DefaultSecurityFilterChain(ignoredRequest));
??????}
??????for (SecurityBuilder<? extends SecurityFilterChain> securityFilterChainBuilder : securityFilterChainBuilders) {
?????????securityFilterChains.add(securityFilterChainBuilder.build());
??????}
??????FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
??????if (httpFirewall != null) {
?????????filterChainProxy.setFirewall(httpFirewall);
??????}
??????filterChainProxy.afterPropertiesSet();
??????Filter result = filterChainProxy;
??????postBuildAction.run();
??????return result;
???}
}
3.小結
? ? ? ? 整個構建過程由beforeInit、init、beforeConfigure、configure、performBuild5大步驟組成。技術層面使用了建造者模式和模板方法模式。
疏漏之處恭請雅正,良策佳議敬候惠示,凡所賜教必當銘感于心。