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.
* 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名字的集合中。