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

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

概述

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

    }

来源:http://ddrv.cn/a/88268

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring Security Config 5.1.2 源码解析 — 工具类 AutowireBeanFactoryObjectPostProcessor

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏