Spring Security Config : 工具类 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()这样的方法也能被执行。

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

源代码版本 5.1.2.RELEASE

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

}

  • 1
    点赞
  • 3
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

安迪源文

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值