Spring(六)核⼼容器-注册单例Bean实例、
SingletonBeanRegistry简介
⽬录
前⾔
上篇⽂章我们对注册 Bean 的核⼼类 BeanDefinitionRegistry 进⾏了讨论,这⾥的注册 Bean 是指保存 Bean 的相关信息,也就是将 Bean 定义成 BeanDefinition,然后放⼊容器中。除此之外,Spring 还提供⼀个统⼀操作单例 Bean 实例的类 SingletonBeanRegistry,通过该类可直接对单例 Bean 的实例进⾏存储、注册等操作。
SingletonBeanRegistry
SingletonBeanRegistry 是⼀个接⼝,其定义了操作单例 Bean 实例的⼀些基础⽅法:
public interface SingletonBeanRegistry {
// 注册单例 Bean。其实就是将该 Bean 保存到⼀个专门存储单例 Bean 实例的Map中,Key是 beanName,Value是对应的单例 Bean 实例
void registerSingleton(String beanName, Object singletonObject);
// 通过 beanName 获取该单例 Bean 实例
Object getSingleton(String beanName);
// 通过 beanName 判断该单例 Bean 实例是否存在
boolean containsSingleton(String beanName);
// 返回所有单例 Bean 的名称
String[] getSingletonNames();
// 返回已注册的单例 Bean 实例数量
int getSingletonCount();
// 返回当前使⽤的单例锁,主要提供给外部协作者使⽤
Object getSingletonMutex();
}
这个接⼝的核⼼实现类是 DefaultSingletonBeanRegistry,该类不仅实现了这些基础⽅法,还针对单例 Bean 扩展了许多功能,如:存储Bean 之间的依赖关系、存储 Bean 的包含关系(外部类包含内部类)、获取 Bean 所处的状态(正在创建、创建完毕等)、回调销毁 Bean 时触发的 destroy ⽅法等。
下⾯是 DefaultSingletonBeanRegistry 类中的核⼼属性和⽅法:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/********** 1、定义的⼀些 Map 属性,⽤来保存单例 Bean 实例、 Bean 的依赖关系 **********/
// 缓存单例 Bean 实例,Key 是 beanName,Value 是单例 Bean 实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 缓存 Bean 对应的 ObjectFactory
//      ObjectFactory 是获取 Bean 实例的⼯⼚,只不过这⾥获取的 Bean 还未完全实例化,属于提早暴露的 Bean
//      该属性在解决循环依赖时使⽤,后续会深⼊讨论
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 缓存 singletonFactories 属性中通过 ObjectFactory 创建的 Bean
//      该属性也是在解决循环依赖时使⽤,后续会深⼊讨论
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 保存已注册的单例 Bean 名称
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
// 保存当前正在创建的 Bean 的名称
private final Set<String> singletonsCurrentlyInCreation = wSetFromMap(new ConcurrentHashMap<>(16));
// 保存当前从创建检查中排除的 Bean 的名称
private final Set<String> inCreationCheckExclusions = wSetFromMap(new ConcurrentHashMap<>(16));
...
// 当前 Bean 是否处于销毁状态
private boolean singletonsCurrentlyInDestruction = false;
// 保存实现了 DisposableBean 接⼝的 Bean,在销毁 Bean 时,会回调该 Bean 中的 destory ⽅法
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
// 保存 Bean 的包含关系,key 是 Bean 的名称,value 是 Bean ⾥⾯包含的其它 Bean 名称集合
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
// 保存 Bean 的依赖关系:key 是 Bean 的名称,value 是依赖于该 Bean 的其它 Bean 名称集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
// 保存 Bean 的依赖关系:key 是 Bean 的名称,value 是该 Bean 所依赖的其它 Bean 名称集合
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);    /******************************** 2、注册单例 Bean 实例及对应的实例⼯⼚ ********************************/    // 注册单例 Bean 实例
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {  Null(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 通过 beanName 获取 Map 中对应的单例 Bean 实例
Object oldObject = (beanName);
//  如果不为空,则抛出异常,因为单例已经存在,⽆法再次注册
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
// 为空,则进⼊ addSingleton ⽅法
addSingleton(beanName, singletonObject);
}
}
// 缓存单例 Bean 实例
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 将单例 Bean 实例存放⾄ singletonObjects 集合
this.singletonObjects.put(beanName, singletonObject);
// 当 beanName 对应的 Bean 实例已被存放⾄ singletonObjects 集合时,singletonFactories
// 和 earlySingletonObjects 集合则不能再持有 beanName 对应的 ObjectFactory 和实例
// 其中原因会在后续循环依赖的⽂章深⼊讨论
ve(beanName);
ve(beanName);
// 存储 Bean 名称
}
}
// 缓存 Bean 对应的 ObjectFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!ainsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
ve(beanName);
}
}
}
/********************************* 3、获取单例 Bean 实例 *********************************/
@Override
public Object getSingleton(String beanName) {
// 该⽅法较为复杂,在后续结合循环依赖的场景讨论
}
...
/***************************** 4、对单例 Bean 实例的基础操作 *****************************/
// 删除单例 Bean 实例
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
ve(beanName);
ve(beanName);
ve(beanName);
}
}
实例化bean的三种方式// 判断 beanName 对应的单例 Bean 实例时候存在
@Override
public boolean containsSingleton(String beanName) {
return ainsKey(beanName);
}
// 返回所有单例 Bean 的 beanName
@Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
isteredSingletons);
}
}
// 返回单例 Bean 实例数量
@Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
isteredSingletons.size();
}
}
...
/*************************************** 5、 Bean 的状态 **************************************/
// beanName 对应的 Bean 是否处于实例化阶段
public boolean isCurrentlyInCreation(String beanName) {
return (!ains(beanName) && isActuallyInCreation(beanName));
}
protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return ains(beanName);
}
// 单例 Bean 实例化前执⾏,将正要创建的 Bean 加⼊ singletonsCurrentlyInCreation 集合
protected void beforeSingletonCreation(String beanName) {
if (!ains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
// 单例 Bean 实例化后执⾏,从 singletonsCurrentlyInCreation 集合中移除已创建的 Bean
protected void afterSingletonCreation(String beanName) {
if (!ains(beanName) && !ve(beanName)) {  throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
...
/********************* 6、存储 Bean 之间的关系、判断 Bean 之间的关系 *********************/
// 保存具有包含关系的 Bean(内部类与外部类)
public void registerContainedBean(String containedBeanName, String containingBeanName) {
synchronized (ainedBeanMap) {
Set<String> containedBeans =
if (!containedBeans.add(containedBeanName)) {
return;
}
}
registerDependentBean(containedBeanName, containingBeanName);
}
// 保存具有依赖关系的 Bean
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMapputeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMapputeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
...
/***************************** 7、销毁 Bean 的⽅法 *****************************/
...
}
DefaultSingletonBeanRegistry 类中的属性及⽅法虽然很多,但也有规律可循的,⼤致分为对单例 Bean 实例的操作、管理 Bean 之间关系、针对 Bean 的不同状态进⾏操作及销毁 Bean 的操作。
该类中的核⼼还是那些 Map,类中的所有⽅法都是对这些 Map 进⾏操作,⽽这些 Map 中存储的是不同场景下的单例 Bean 。
最后
关于 SingletonBeanRegistry 就介绍到这,其主要还是针对单例 Bean 进⾏操作,外部调⽤者统⼀继承该类操作单例 Bean,其主要调⽤者还是 DefaultListableBeanFactory,前篇⽂章也说过,这是我们当前上下⽂环境中使⽤的 BeanFactory ⼯⼚类,在⼯⼚类中执⾏ getBean 操作时,会调⽤这些⽅法,后续会详细讨论 getBean 操作。最后值得注意是,Spring 也是在该类中解决循环依赖问题,这部分也会在后⾯详细讨论。