【源码】Spring —— SingletonBeanRegistry 解读
前言
单例(singleton
),是我们使用 Spring IoC Container
时最常见的 bean
实例作用域类型(Scope
),因此对于单例的维护与管理,Spring
单独抽象 SingletonBeanRegistry
接口来维护
职 责 分 明
版本
Spring 5.2.x
SingletonBeanRegistry
public interface SingletonBeanRegistry {
/**
* 单例的注册,如果脱离生命周期单独调用该方法,就是单纯的注册而不执行
* 诸如生命周期回调等相关
* 通常,是容器在基于 BeanDefinition 创建 singleton 时调用该方法的
*/
void registerSingleton(String beanName, Object singletonObject);
/**
* 获取以及实例化完成的 singleton
* 1)手动 registerSingleton 注册的
* 2)容器基于 BeanDefinition 实例化完成后注册的
*/
@Nullable
Object getSingleton(String beanName);
/**
* 检查指定 singleton 是否存在
* 该方法 + ListableBeanFactory#containsBeanDefinition:可以查看当前容器中是否可以
* 获取到指定 name 的 bean,无论它是否实例化完成
* BeanFactory#containsBean 在上一步基础上,还可以查找父级容器
*/
boolean containsSingleton(String beanName);
// 上述 singleton 名称数组
String[] getSingletonNames();
// 上述 singleton 个数
int getSingletonCount();
// 单例锁对象
Object getSingletonMutex();
}
XXXRegistry
,这种命名在Spring
中通常扮演注册中心的职责,维护管理对应的一组实例,此处管理的就是singleton
,即容器中最常见作用域的实例- 单例通常来自
Spring IoC Container
在配置解析后,基于BeanDefinition
的注册 - 同时我们也可以在容器生命周期之外自行调用
registerSingleton
方法注册,对于这部分实例的生命周期,自然不由容器管理 - 该接口提供的方法就是基于上述两种
singleton
而言
DefaultSingletonBeanRegistry
核心属性
// 单例缓存 beanName -> 单例实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 工厂缓存,又称二级缓存,缓存单例工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 三级缓存,缓存提前暴露的单例实例
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 缓存以及注册单例的单例名称(按注册顺序)
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
// 正在创建的 bean 的 name
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
// 是否允许 循环引用
private boolean singletonsCurrentlyInDestruction = false;
//...
- 定义了大量的 缓存 属性,用于解决 循环依赖,提高性能 等
- 其中
singletonObjects
即我们常说的 单例池,所有的 单例 都在创建完成后缓存其中
registerSingleton(String beanName, Object singletonObject)
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
// 重复注册抛异常 IllegalStateException
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
if (oldObject != null) {
throw new IllegalStateException("...");
}
// 单例注册
addSingleton(beanName, singletonObject);
}
}
protected void addSingleton(String beanName, Object singletonObject) {
/**
* 加入一级缓存
* 二三级缓存移除
* registeredSingletons 缓存 beanName
*/
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
单例注册, 即放入 singletonObjects
单例池中,并清除其他无效缓存
getSingleton(String beanName)
// 单例获取
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
// 获取目标单例,没有则创建
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
// 未获取到且未在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 三级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
// 获取不到且允许循环依赖,继续去二级缓存获取
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 从二级工厂缓存获取对应单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 如果存在,则获取对应单例,加入三级缓存,移出二级缓存
// 此举是为了性能优化,因为单例工厂创建单例可能会产生巨大的性能开销(比如代理)
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
- 试图获取单例,会依次从各级 缓存 中获取
- 二级缓存 内部是提前暴露的 单例工厂 ,三级缓存 是将 单例工厂 创建的实例缓存起来,它们是分别为了解决 循环依赖 和 优化性能
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
// 从给定 singletonFactory 创建对应单例并注册
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 一级缓存获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 正在创建中抛异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"...");
}
// 加入 singletonsCurrentlyInCreation 缓存
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
// 初始化 suppressedExceptions
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 单例工厂获取对应单例实例
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
//...
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 从 singletonsCurrentlyInCreation 移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 注册单例
addSingleton(beanName, singletonObject);
}
}
// 返回
return singletonObject;
}
}
从给定 单例工厂 创建对应 单例 并注册
其他方法
// 单例移除,从所有缓存中移除
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
@Override
// 是否存在指定 beanName 对应的 单例
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
}
@Override
// 获取所有单例 name
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
@Override
// 单例数
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
FactoryBeanRegistrySupport
有一部分单例可能会是 FactoryBean
,这部分单例的相关方法由 FactoryBeanRegistrySupport
拓展 DefaultSingletonBeanRegistry
提供
属性
// bean 缓存 (FactoryBeanName -> bean实例)
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
FactoryBean
维护的单例的缓存
getTypeForFactoryBean(FactoryBean<?> factoryBean)
@Nullable
// 确定给定 工厂bean 的类型
protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
try {
// ...
else {
return factoryBean.getObjectType();
}
}
catch (Throwable ex) {
// 略
}
}
FactoryBean 的类型获取,实际就是 factoryBean.getObjectType()
getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)
// 获取 工厂bean 对应的 bean实例
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 是单例bean && 已注册
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 获取工厂缓存的 bean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 从 工厂bean 获取 bean实例
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 有必要的话调用 后处理 方法
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
return object;
}
beforeSingletonCreation(beanName);
try {
// 后处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
//...
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
// 不是单例 || 还没注册过
else {
// 获取单例实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 有必要的话调用 后处理 方法
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
//...
}
}
return object;
}
}
- 最终都是委托到方法
doGetObjectFromFactoryBean
- 这里允许对获取的实例进行后处理,比如执行
post processor
doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName)
// 获取指定 工厂bean 创建的 bean实例
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
// 略
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
// 略
}
// 略
return object;
}
简单地说就是 FactoryBean#getObject
postProcessObjectFromFactoryBean(Object object, String beanName)
// 后处理方法由子类复写
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
对最终的实例进行后处理
如果目标 `bean` 实例是个 `FactroyBean`,那容器的生命周期只
对该 FactroyBean 生效,因此此处允许对真正的实例进行后处理
比如 AbstractAutowireCapableBeanFactory 会覆写该方法:执
行容器中所有的 BeanPostProcessor#postProcessAfterInitialization
其他方法
// 获取给定 beanName 和 bean实例 对应的 工厂bean
protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanCreationException(beanName,
"...");
}
return (FactoryBean<?>) beanInstance;
}
@Override
// 单例移除,同时从本类的缓存中移除
protected void removeSingleton(String beanName) {
synchronized (getSingletonMutex()) {
super.removeSingleton(beanName);
this.factoryBeanObjectCache.remove(beanName);
}
}
@Override
// 清缓存同理
protected void clearSingletonCache() {
synchronized (getSingletonMutex()) {
super.clearSingletonCache();
this.factoryBeanObjectCache.clear();
}
}
// ...
还提供了 FactoryBean 的获取、单例移除 等方法
总结
SingletonBeanRegistry
接口把容器对 singleton
的维护管理单独抽象了出来,其中:
DefaultSingletonBeanRegistry
提供对常规单例的维护,其最终会维护在一个缓存Map
中即我们通常所说的单例池
,同时它借助二级缓存(工厂缓存)
三级缓存(优化二级缓存创建实例的开销)
来解决循环依赖
的问题- 针对
FactoryBean
类型的singleton
,对应的方法由FactoryBeanRegistrySupport
提供,比如类型的获取
最终实例的获取
实例后处理
等