SingletonBeanRegistry接口分析(一)

本文深入解析了Spring框架中的SingletonBeanRegistry接口及其DefaultSingletonBeanRegistry实现类。详细介绍了SingletonBeanRegistry的功能,包括单例Bean的注册、获取和管理,并探讨了DefaultSingletonBeanRegistry类的内部属性和注册Bean的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SingletonBeanRegistry是单例Bean的注册中心
接口中一共定义了6个方法

//检查此注册表是否包含具有给定名称的单例实例。
boolean	containsSingleton(String beanName)
//返回在给定名称下注册的(原始)单例对象。
Object getSingleton(String beanName)
//返回在此注册表中注册的单例bean的数量。
int	getSingletonCount()
//返回此注册表使用的单例互斥锁(对于外部协作者)。
Object getSingletonMutex()
//返回在此注册表中注册的单例bean的名称。
String[] getSingletonNames()
//在给定的bean名称下,在bean注册表中将给定的现有对象注册为singleton。
void registerSingleton(String beanName, Object singletonObject)

在这里插入图片描述
可以看到DefaultSingletonBeanRegistry类,它继承了SimpleAlasRegistry类,实现了SingletonBeanRegistry接口,是SingletonBeanRegistry接口的直接实现类。因此该类具有别名注册(AlasRegistry)功能和单例注册(SingletonBeanRegistry)功能。
在DefaultSingletonBeanRegistry,定义了以下几个属性:

/** 
Cache of singleton objects: bean name to bean instance. 
用ConcurrentHashMap来保存单例对象,其中key是单例对象的名字 
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 
Cache of singleton factories: bean name to ObjectFactory. 
用HashMap来保存制作单例的工厂对象
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 
Cache of early singleton objects: bean name to bean instance. 
用HashMap来保存单例工厂制造出来的早期单例对象
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 
Set of registered singletons, containing the bean names in registration order. 
用Set来存储单例对象的名称
*/
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** 
Names of beans that are currently in creation. 
正在创建的bean的名称。
*/
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** 
Names of beans currently excluded from in creation checks. 
当前从创建检查中排除的bean的名称。
*/
private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/** 
List of suppressed Exceptions, available for associating related causes. 
存放出现异常的原因,可用于关联相关原因。
@Nullable表示可以为空
*/
@Nullable
private Set<Exception> suppressedExceptions;
/** 
Flag that indicates whether we're currently within destroySingletons. 
标志,表明我们目前是否在销毁单例。
*/
private boolean singletonsCurrentlyInDestruction = false;
/** 
Disposable bean instances: bean name to disposable instance. 
存放一次性bean
*/
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
/** 
Map between containing bean names: bean name to Set of bean names that the bean contains. 
存放bean之间的依赖关系,例如beanA依赖beanB、beanC,则在Map中保存key为beanA,value为beanB和beanC的集合。
*/
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** 
Map between dependent bean names: bean name to Set of dependent bean names.
从属bean名称之间的映射:bean名称到依赖bean名称的集合。 
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** 
Map between depending bean names: bean name to Set of bean names for the bean's dependencies. 
依赖bean名称之间的映射:bean名称到bean依赖项的bean名称。
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);

首先看一下注册bean的方法:

@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
	Assert.notNull(beanName, "Bean name must not be null");
	Assert.notNull(singletonObject, "Singleton object must not be null");
	synchronized (this.singletonObjects) {
		Object oldObject = this.singletonObjects.get(beanName);
		if (oldObject != null) {
			throw new IllegalStateException("Could not register object [" + singletonObject +
					"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
		}
		addSingleton(beanName, singletonObject);
	}
}

可以看到,该方法很简单,如果bean的名字或者bean对象是null的情况下,会抛出异常。
如果均不为空,则用bean的名字尝试从singletonObjects单例的缓存中取出单例,如果取到了bean,则抛出异常,因为单例已经存在了,无法再次注册。
否则的话进入到addSingleton方法。

/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

addSingleton方法会将单例bean放入到singletonObjects单例bean的缓存中,
同时会从singletonFactories单例bean工厂、earlySingletonObjects旧的单例bean对象缓存中移除工厂和bean。并将单例bean的名字加到registeredSingletonsy一个存放单例bean名字的集合中。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值