DefaultSingletonBeanRegistry
英文注释分别阐述了以下内容(一个段落用一个小标):
⑴、类DefaultSingletonBeanRegistry实现了接口SingletonBeanRegistry,是通用注册表的基础实现类:
①、它允许注册bean对象实例(这些对象实例都是单例模式)。
②、已经注册的bean对象实例是注册表的所有调用者共享的(所以特别需要注意线程安全)。
③、可以通过bean名称获得目标bean对象实例。
⑵、类DefaultSingletonBeanRegistry还支持类DisposableBean对象实例的注册(在关闭注册表时销毁),该实例可能与已注册的bean对象实例相对应。bean对象实例之间的依赖关系也可以注册,以此控制销毁bean对象实例的顺序。
⑶、类DefaultSingletonBeanRegistry主要作为实现接口BeanFactory的基类,它分解了单例bean对象实例的常见管理(比如注册,获取等等,但不包含创建)。
①、另一个接口ConfigurableBeanFactory扩展了接口SingletonBeanRegistry。
⑷、类DefaultSingletonBeanRegistry与类AbstractBeanFactory和类DefaultListableBeanFactory(继承自类DefaultSingletonBeanRegistry)相比,既不涉及bean对象实例概念的定义也不涉及bean对象实例的创建过程,还可以用作委托的嵌套助手(涉及Java设计模式)。
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry
implements SingletonBeanRegistry {
//单例bean对象实例都存储在Map中,但Map不允许存储null
//所以当bean为null时,就用NULL_OBJECT代替null存储到Map中
protected static final Object NULL_OBJECT = new Object();
//日志对象,供子类使用
protected final Log logger = LogFactory.getLog(getClass());
//存储已经创建完毕的单例bean对象实例
//(创建完毕是指构造方法已经执行
//并且属性也已经根据配置文件赋值完毕)
//singletonObjects也称为三级缓存
private final Map<String, Object> singletonObjects = new
ConcurrentHashMap<String, Object>(256);
//存储创建单例bean对象实例的工厂对象实例
//一个工厂对象实例创建一种类型bean
//具体的创建过程在类DefaultListableBeanFactory中
//所有的工厂类都需要implements接口ObjectFactory<?>
//singletonFactories也称为一级缓存(必须先有工厂才能创建bean)
private final Map<String, ObjectFactory<?>> singletonFactories =
new HashMap<String, ObjectFactory<?>>(16);
//Spring创建bean对象实例大多都是调用默认构造函数
//再通过set方法为属性赋值
//存储已经执行默认构造函数但未给属性赋值的对象
//earlySingletonObjects也称为二级缓存
//主要解决bean之间循环依赖的问题
//(需要明白循环依赖问题后面的源码才能看的懂)
//Spring中的循环依赖有三种:
//①、类A类B互为构造方法依赖
//这种依赖Spring无法解决:创建类A对象的时候
//发现类A的构造方法参数为类B对象,这时候需要
//创建类B对象,但是又发现类B的构造方法参数为类A对象
//结果类A和类B对象都无法创建
//②、类A的构造方法参数为类B对象,类B的某个
//setter方法参数为类A对象,创建类A对象的时候
//需要创建类B对象可以直接通过类B的默认构造方法
//类B对象创建完毕后类A对象的创建过程得以继续
//这时类B对象需要暂时放入earlySingletonObjects缓存中
//因为它只创建了对象,并未给属性赋值
//③、类A类B互为setter方法参数依赖,举例与第二种
//情况类似,都是通过默认构造方法创建对象
//这时类A与类B都会被放入earlySingletonObjects缓存中
private final Map<String, Object> earlySingletonObjects =
new HashMap<String, Object>(16);
//存储已经创建完毕的单例bean对象实例的名称
//(创建完毕是指构造方法已经执行
//并且属性也已经根据配置文件赋值完毕)
//存储的顺序是单例bean对象实例的注册顺序
private final Set<String> registeredSingletons =
new LinkedHashSet<String>(256);
//存储正在创建的bean对象实例的名称
//(正在创建是指构造方法已经执行
//所有或者部分属性还未根据配置文件赋值)
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
//
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
//禁止的异常,可用于关联相关原因
private Set<Exception> suppressedExceptions;
//指示我们当前是否在destroySingletons中的标志
private boolean singletonsCurrentlyInDestruction = false;
private final Map<String, Object> disposableBeans =
new LinkedHashMap<String, Object>();
private final Map<String, Set<String>> containedBeanMap =
new ConcurrentHashMap<String, Set<String>>(16);
private final Map<String, Set<String>> dependentBeanMap =
new ConcurrentHashMap<String, Set<String>>(64);
private final Map<String, Set<String>> dependenciesForBeanMap =
new ConcurrentHashMap<String, Set<String>>(64);
//在注册表(Map)中注册一个已经创建完毕的单例bean
//对象实例singletonObject,名称为指定名称beanName
public void registerSingleton(String beanName, Object singletonObject)
throws IllegalStateException {
//保证指定名称beanName不为null
Assert.notNull(beanName, "'beanName' must not be null");
//因为注册表中的单例bean对象实例是它的所有调用者共享的
//所以在多线程环境下同一时间内只能有一个调用者操作
//singletonObjects,需要通过关键字synchronized保证线程安全
synchronized (this.singletonObjects) {
//判断指定名称beanName是否已经注册,通过它
//去一级缓存中获取对象
Object oldObject = this.singletonObjects.get(beanName);
//如果oldObject != null,说明beanName已经注册
if (oldObject != null) {
//直接抛出异常,并提示已注册的名称不能重复注册
//因为Map的key是唯一的
throw new IllegalStateException("Could not register object
[" + singletonObject +"] under bean name '" + beanName + "':
there is already object [" + oldObject + "] bound");
}
//如果oldObject == null,说明beanName未注册
//继续执行注册流程,参考方法
//addSingleton(String beanName, Object singletonObject)
addSingleton(beanName, singletonObject);
}
}
//向注册表的一级缓存中添加已经
//创建完毕的单例bean对象实例singletonObject
protected void addSingleton(String beanName, Object singletonObject) {
//保证线程安全
synchronized (this.singletonObjects) {
//向一级缓存中添加键值对beanName->singletonObject
//因为Map不允许添加null,如果singletonObject == null
//就用NULL_OBJECT代替
this.singletonObjects.put(beanName, (singletonObject != null ?
singletonObject : NULL_OBJECT));
//singletonObject是已经创建完毕的单例bean对象实例
//所以三级缓存中的记录需要删除
//(如果有,如果没有,remove()不会执行任何操作)
//从另一个角度理解:因为是单例,既然已经有已经创建完毕的
//singletonObject,自然不再需要创建的工厂,所以删除
this.singletonFactories.remove(beanName);
//同样,二级缓存中的记录也需要删除
//(如果有,如果没有,remove()不会执行任何操作)
this.earlySingletonObjects.remove(beanName);
//将beanName添加到存储已经创建完毕的
//单例bean实例对象的名称集合中
//在添加三级缓存的方法addSingletonFactory
//(String beanName, ObjectFacto