Spring Security Config 5.1.2 源码解析 -- 工具类 AutowireBeanFactoryObjectPostProcessor

概述

Spring Security的配置机制会使用到很多对象,比如WebSecurity,ProviderManager,各个安全Filter等。这些对象的创建并不是通过bean定义的形式被容器发现和注册进入容器的。而是由Spring Security配置机制使用Java new操作符创建。但对于这些并未被容器管理的对象,Spring Security配置机制也称之为bean,并且希望它们也经历跟容器bean同样的生命周期,也能注入相应的依赖,从而进入准备好被使用的状态。为达成这个目标,Spring Security配置机制提供了一个工具类AutowireBeanFactoryObjectPostProcessor

工具类AutowireBeanFactoryObjectPostProcessor本身会被注册成为容器的一个bean,并且它实现了Spring bean基本的DisposableBean,SmartInitializingSingleton生命周期接口,也就是说它会经历容器标准的生命周期方法调用。在此基础之上,AutowireBeanFactoryObjectPostProcessor又实现了另外一个接口ObjectPostProcessor,这是一个Spring Security自己定义的接口,用来初始化某个新建的对象,通常就是调用其可能带有的跟Aware方法,InitializingBean#afterPropertiesSet()方法同样设计目的的各个初始化方法,并保证DisposableBean#destroy()这样的方法也能被执行。

具体我们通过代码来分析。

AutowireBeanFactoryObjectPostProcessor被注册为容器bean

当使用了注解@EnableWebSecurity,或者@EnableGlobalMethodSecurity时,AutowireBeanFactoryObjectPostProcessor会被注册为一个容器bean

// @EnableWebSecurity 注解代码片段,可以看到该注解隐含使用了@EnableGlobalMethodSecurity
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {

    /** * Controls debugging support for Spring Security. Default is false. * @return if true, enables debug support with Spring Security */
    boolean debug() default false;
}
// @EnableGlobalAuthentication 注解代码片段,可以看到它导入了类 AuthenticationConfiguration
@Import(AuthenticationConfiguration.class)
@Configuration
public @interface EnableGlobalAuthentication {
}

从上面的代码片段来看,不管使用了@EnableWebSecurity还是@EnableGlobalAuthentication,最终都会导入类AuthenticationConfiguration :

@Configuration
@Import(ObjectPostProcessorConfiguration.class) // 导入了类 ObjectPostProcessorConfiguration
public class AuthenticationConfiguration {
    // 省略无关代码实现
}

而类AuthenticationConfiguration又导入了类ObjectPostProcessorConfiguration,ObjectPostProcessorConfiguration进一步注册了bean AutowireBeanFactoryObjectPostProcessor :

@Configuration
public class ObjectPostProcessorConfiguration {

    // 这里的参数beanFactory会被自动注入成当前Spring bean容器
    @Bean
    public ObjectPostProcessor<Object> objectPostProcessor(
            AutowireCapableBeanFactory beanFactory) {
        return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
    }
}

AutowireBeanFactoryObjectPostProcessor的任务

package org.springframework.security.config.annotation.configuration;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.util.Assert;

final class AutowireBeanFactoryObjectPostProcessor
        implements ObjectPostProcessor<Object>, DisposableBean, SmartInitializingSingleton {
    private final Log logger = LogFactory.getLog(getClass());
    private final AutowireCapableBeanFactory autowireBeanFactory;
    private final List<DisposableBean> disposableBeans = new ArrayList<>();
    private final List<SmartInitializingSingleton> smartSingletons = new ArrayList<>();

    // 使用指定的 autowireBeanFactory 构造对象
    // autowireBeanFactory 通常是 Spring bean 容器
    public AutowireBeanFactoryObjectPostProcessor(
            AutowireCapableBeanFactory autowireBeanFactory) {
        Assert.notNull(autowireBeanFactory, "autowireBeanFactory cannot be null");
        this.autowireBeanFactory = autowireBeanFactory;
    }

    
    // 对某个刚刚创建的对象 object 执行这里所谓的 post-process 流程 :
    // 1. 使用指定的 autowireBeanFactory 对该对象 object 执行初始化过程;
    // 2. 使用指定的 autowireBeanFactory 对该对象 object 执行依赖注入过程;
    // 3. 如果该对象 object 是一个 DisposableBean , 则将它记录下来,在当前对象的destroy()
    // 被调用时,它们的 destroy() 方法也都会被调用;
    // 4. 如果该对象 object 是一个 SmartInitializingSingleton , 则将它记录下来,
    // 在当前对象的 afterSingletonsInstantiated () 被调用时,它们的 afterSingletonsInstantiated() 
    // 方法也都会被调用;
    @SuppressWarnings("unchecked")
    public <T> T postProcess(T object) {
        if (object == null) {
            return null;
        }
        T result = null;
        try {
            // 使用容器autowireBeanFactory标准初始化方法initializeBean()初始化对象 object
            result = (T) this.autowireBeanFactory.initializeBean(object,
                    object.toString());
        }
        catch (RuntimeException e) {
            Class<?> type = object.getClass();
            throw new RuntimeException(
                    "Could not postProcess " + object + " of type " + type, e);
        }
        // 使用容器autowireBeanFactory标准依赖注入方法autowireBean()处理 object对象的依赖注入
        this.autowireBeanFactory.autowireBean(object);
        
        if (result instanceof DisposableBean) {
            // 记录一个 DisposableBean 对象
            this.disposableBeans.add((DisposableBean) result);
        }
        if (result instanceof SmartInitializingSingleton) {
            // 记录一个 SmartInitializingSingleton 对象
            this.smartSingletons.add((SmartInitializingSingleton) result);
        }
        return result;
    }
    
    // SmartInitializingSingleton 接口定义的生命周期方法,在被调用时也回调用被记录的实现了
    // SmartInitializingSingleton 接口的那些对象的方法 afterSingletonsInstantiated()
    @Override
    public void afterSingletonsInstantiated() {
        for (SmartInitializingSingleton singleton : smartSingletons) {
            singleton.afterSingletonsInstantiated();
        }
    }

    // DisposableBean 接口定义的生命周期方法,在被调用时也回调用被记录的实现了
    // DisposableBean 接口的那些对象的方法 destroy()
    public void destroy() throws Exception {
        for (DisposableBean disposable : this.disposableBeans) {
            try {
                disposable.destroy();
            }
            catch (Exception error) {
                this.logger.error(error);
            }
        }
    }

}

    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/andy_zhang2007/article/details/84970156
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞