SpringSecurity源码学习(二)

前言

本章讨论SpringSecurity中的构建器。

构建器

SecurityBuilder< O>

构建器的顶级接口,下文中所有”构建器”指的就是它或它的子类。只有一个方法:

O build() throws Exception;

ps:泛型O,指的是被构建的对象的类型。

AbstractSecurityBuilder< O>

构建器接口抽象实现。主要做的事情是,保证在多线程的情况下,只构建一次对象。

这里没有使用synchronized,而是使用jdk中高大上的解决线程同步的方法:cas。当然这个不是我们讨论的重点。要记住的是继承了AbstractSecurityBuilder的构建器,在多线程的情况下只会创建一次,具体创建的方法是:

//build()--->doBuild();
protected abstract O doBuild() throws Exception;

ps:泛型O,指的是被构建的对象的类型。

AbstractConfiguredSecurityBuilder< O, B extends SecurityBuilder< O>>

可配置的构建器。PS:O还是指的是被构建的对象类型,而B指的是构建O这个对象的构建器的类型。

它的几个重要的属性:

    //构建器的配置器的集合
    LinkedHashMap configurers;
    //构建器的配置器共享的对象
    HashMap sharedObjects;
    //后置处理器
    ObjectPostProcessor objectPostProcessor

configurers属性的要注意的是,它的add方法叫:apply(configurer);这个在后面还会常用到。
在它的父类中,我们就知道,build委托给doBuild()来做具体的构建工作,而前者主要负责多线程情况下不重复创建。那么这个方法在子类中是怎样实现的呢?如下:

    @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;
        }
    }

典型“模版方法”设计模式。父类定义步骤及顺序,具体实现由子类完成。当然,这里init()和configure()父类已经给出了实现,无需子类实现:

    private void init() throws Exception {
        Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

        for (SecurityConfigurer<O, B> configurer : configurers) {
            configurer.init((B) this);
        }
        //ps:老实说,写这篇文章的时候,configurersAddedInInitializing和configurers还不是很清楚...
        for (SecurityConfigurer<O, B> configurer : configurersAddedInInitializing) {
            configurer.init((B) this);
        }
    }
    private void configure() throws Exception {
        Collection<SecurityConfigurer<O, B>> configurers = getConfigurers();

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

我们在看下它的继承关系:

这里写图片描述

三个子类,都是非常非常非常重要的构建器。

  1. AuthenticationManagerBuilder,用来构建授权管理器
  2. WebSecurity,用来构建“过滤器链的代理”
  3. HttpSecurity,用来构建“过滤器链”

AuthenticationManagerBuilder

看它的结构:

这里写图片描述

注意到它实现了ProviderManagerBuilder< AuthenticationManagerBuilder>接口,这个接口是用来构建ProviderManager。ProviderManager是AuthenticationManager的子类。

AuthenticationManagerBuilder的功能是创建AuthenticationManager

WebSecurity

它是为了创建“过滤器链代理”,即:FilterChainProxy对象。

这里写图片描述

正是FilterChainProxy的创建,触发了HttpSecurity的构建。

FilterChainProxy

一个SecurityFilterChain对象就是一个“过滤器链代理”,它包含了多条过滤器链。当请求来的时候,迭代这些链,看哪条链能处理该请求就将请求交给此链处理,其他链不再处理。

WebSecurityConfiguration

WebSecurity的构建是由它触发的。在前面我们知道,这个配置类是被@EnableWebSecurity注解导入的。

    @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
    public Filter springSecurityFilterChain() throws Exception {
        boolean hasConfigurers = webSecurityConfigurers != null
                && !webSecurityConfigurers.isEmpty();
        if (!hasConfigurers) {
            WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
                    .postProcess(new WebSecurityConfigurerAdapter() {
                    });
            webSecurity.apply(adapter);
        }
        return webSecurity.build();
    }

分析构建过程:

这里写图片描述

1、WebSecurityConfiguration 触发了构建过程

2、AbstractSecurityBuilder 保证在多线程情况下只构建一次

3、AbstractConfiguredSecurityBuilder 定义了构建的模版

4、WebSecurityConfigurerAdapter是构建时要使用的配置类(其中init()方法创建了HttpSecurity)

5、WebSecurity负责最终构建出FilterChainProxy

6、最终WebSecurityConfiguration将它放在容器中准备接受委派。

HttpSecurity

它是为了构建过滤器链。即:DefaultSecurityFilterChain。DefaultSecurityFilterChain才是真正用来处理请求的。所以用到了很多组件。


这里写图片描述

看它的构建过程:


这里写图片描述

这个是重点,后面详细讨论。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值