总览
共享bean实例的通用注册表,实现了SingletonBeanRegistry. 允许注册表中注册的单例应该被所有调用者共享,通过bean名称获得。
还支持登记的DisposableBean实例,(这可能会或不能正确的注册单例),关闭注册表时destroyed. 可以注册bean之间的依赖关系,执行适当的关闭顺序。
这个类主要用作基类的BeanFactory实现, 提供基本的管理 singleton bean 实例功能。
注意:与AbstractBeanFactory跟DefaultListableBeanFactory不同,这个类既不是一个bean definition概念的标识,也不标识特定的创建过程。也可以作为嵌套的助手来委托。
继承体系
SimpleAliasRegistry
实现了注册别名接口
SingletonBeanRegistry
单例bean注册接口
方法列表
序号 | 方法名称 | 描述 |
---|---|---|
1 | void registerSingleton(String beanName, Object singletonObject); | 注册一个单例 |
2 | Object getSingleton(String beanName); | 给定名称返回一个单例 |
3 | boolean containsSingleton(String beanName); | 是否包含给定名字的单例 |
4 | String[] getSingletonNames(); | 返回所有单例名 |
5 | int getSingletonCount(); | 返回单例次数 |
6 | Object getSingletonMutex(); | ??? |
分析
DefaultSingletonBeanRegistry主要是通过内部的几个map对象(SingletonFactories,earlySingletonObjects,singletonObjects)来保存注册的Bean。
对应关系是:
SingletonFactories维护了这个beanName的ObjectFactory。ObjectFactory通过getObject方法获取到了earlySingletonBean,然后在由earlySingletonBean成为bean的实例。
各个SingletonObject之间的关系也是由几个map对象维护(containedBeanMap,dependentBeanMap,dependenciesForBeanMap)。
containedBeanMap(被包含关系:key被value所包含):key是被包含的bean, value则是包含该Bean的所有的bean。(在发现销毁时:value也要被销毁)
dependentBeanMap(被依赖关系:key被value锁依赖):key是被依赖的bean,value则是依赖于该bean的所有bean。(在发生销毁时:value要先于bean被销毁)
dependenciesForBeanMap(依赖关系:key依赖于value):key表示的bean依赖于value表示的Bean。
在注册两个bean包含关系的时候,同时要注册他们的依赖关系。
问题
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
// 已经存在该单例bean的实例,因此对应的工厂和earlySingleton不在需要了
this.singletonFactories.remove(beanName);
// TODO 这个还不知道是干嘛的
this.earlySingletonObjects.remove(beanName);
// 添加进注册表
this.registeredSingletons.add(beanName);
}
}
- 这些方法为什么不用ConcurrentHashMap
- earlySingletonObjects这个是干什么的?
- 如何解析循环引用
/**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
*
* 被要求立即注册单例,例如能够解析循环引用
*
* TODO 如何解析循环引用
*
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}