SingletonBeanRegistry接口分析(一)

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)

SingletonBeanRegistry接口分析(一)_第1张图片
可以看到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名字的集合中。

你可能感兴趣的:(SingletonBeanRegistry接口分析(一))