DefaultSingletonBeanRegistry是接口SingletonBeanRegistry的具体实现,实现了对单例的注册及获取等相关操作。
相关源码分析:
/**
* 单例注册、获取等具体实现
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/**
* 内部使用,由于Spring内部不支持null,用该常量表示空的单例对象
*/
protected static final Object NULL_OBJECT = new Object();
protected final Log logger = LogFactory.getLog(getClass());
/**
* 单例对象缓存,key:beanName value:instance
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/**
* 单例工厂缓存,key:beanName value:ObjectFactory
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/**
* early单例对象缓存(不是很明白什么叫early singleton),key:beanName value:instance
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/**
* 已经注册的单例集合,包括注册队列里bean的name
*/
private final Set<String> registeredSingletons = new LinkedHashSet<String>(256);
/**
* 目前正在创建的bean的name列表
*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/**
* 目前正在从创建检查中移除的bean的name列表
*/
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/**
* suppressed exception列表
*/
private Set<Exception> suppressedExceptions;
/**
* 所有单例当前是否正在被销毁
*/
private boolean singletonsCurrentlyInDestruction = false;
/**
* 一次性使用的单例对象缓存,key:beanName value:instance
*/
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
/**
* key:beanName value:bean包含的bean name列表
*/
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
/**
* key:beanName value:bean依赖的bean name列表
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/**
* key:beanName value:bean依赖的beans' names列表
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
/**
* 单例注册
* @param beanName beanName
* @param singletonObject 类的实例
* @throws IllegalStateException
*/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
//参数校验
Assert.notNull(beanName, "'beanName' 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配置一个实例
* @param beanName
* @param singletonObject
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
//注册单例成功后从单例工厂缓存中移除
this.singletonFactories.remove(beanName);
//注册单例成功后从early singleton缓存中移除
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
/**
* 在单例工厂中为该bean创建一个工厂,这一步骤在注册单例之前完成
* @param beanName
* @param singletonFactory
*/
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);
}
}
}
/**
* 根据beanName获取单例
* @param beanName bean name
* @return instance
*/
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
/**
* 根据beanName获取单例
* 大致几个步骤:
* 1.先从单例对象的缓存中取,假如能取到说明当前bean已经有单例了,直接取出来即可;
* 2.从单例对象缓存中取不到,说明该bean正在创建或者没有完成创建:
* 1)如果bean正在创建,去early singleton缓存中取(在注册成功之前,early singleton和beanFactory已经初始化好),
* 能从early singleton中取到,直接返回,假如取不到,说明该bean还在单例工厂阶段,假如允许注册前可以被引用,可以
* 直接去单例工厂取,无需等到注册完毕之后再取;
* 2)如果bean并没有完成创建,之间返回null。
* 5.前面几个步骤都没有取到,说明该bean没有单例,返回null
* @param beanName bean name
* @param allowEarlyReference instance
* @return
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从单例对象缓存中取出instance
Object singletonObject = this.singletonObjects.get(beanName);
//instance为null或者该bean正在创建单例
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//可以从early singleton缓存中取
singletonObject = this.earlySingletonObjects.get(beanName);
//early singleton中取到的instance还是为空
if (singletonObject == null && allowEarlyReference) {
//取该bean的单例工厂,从工厂中取instance
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
/**
* 从bean的单例工厂中获取instance
* @param beanName bean name
* @param singletonFactory 单例工厂
* @return instance
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//参数校验
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
}
/**
* 移除bean的单例,实质上是移除几个缓存里面该bean对应的数据
* @param beanName bean name
*/
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
/**
* 判断该bean是否已经有注册的单例
* @param beanName bean name
* @return
*/
@Override
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
}
/**
* 获取所有已注册单例的bean的name
* @return
*/
@Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
/**
* 计算已注册的单例数量
* @return
*/
@Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
/**
* 设置bean是否正在创建
* @param beanName bean name
* @param inCreation 是否正在创建
*/
public void setCurrentlyInCreation(String beanName, boolean inCreation) {
//参数校验
Assert.notNull(beanName, "Bean name must not be null");
//假若还没被创建
if (!inCreation) {
this.inCreationCheckExclusions.add(beanName);
}
//已经被创建
else {
this.inCreationCheckExclusions.remove(beanName);
}
}
/**
* 判断bean instance是否正在被创建
* @param beanName
* @return
*/
public boolean isCurrentlyInCreation(String beanName) {
//参数校验
Assert.notNull(beanName, "Bean name must not be null");
return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
}
/**
* 判断bean instance是否正在被创建
* @param beanName bean name
* @return
*/
protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
}
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
/**
* 判断bean是否在创建instance之前
* @param beanName
*/
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
/**
* 判断bean是否在创建instance之后
* @param beanName
*/
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
/**
* 注册一次性使用的单例
* @param beanName
* @param bean
*/
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
/**
* 注册两个bean之间的一个包含关系
* @param containedBeanName
* @param containingBeanName
*/
public void registerContainedBean(String containedBeanName, String containingBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans != null && containedBeans.contains(containedBeanName)) {
return;
}
// No entry yet -> fully synchronized manipulation of the containedBeans Set
synchronized (this.containedBeanMap) {
containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans == null) {
containedBeans = new LinkedHashSet<String>(8);
this.containedBeanMap.put(containingBeanName, containedBeans);
}
containedBeans.add(containedBeanName);
}
//注册依赖
registerDependentBean(containedBeanName, containingBeanName);
}
/**
* 为bean注册一个依赖的bean
* @param beanName bean name
* @param dependentBeanName 依赖的bean name
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
String canonicalName = canonicalName(beanName);
//是否已经有依赖的bean,有的话不需要再注册
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// No entry yet -> fully synchronized manipulation of the dependentBeans Set
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
}
/**
* 判断两个bean是否已经被注册依赖关系
* @param beanName the name of the bean to check
* @param dependentBeanName the name of the dependent bean
* @return
*/
protected boolean isDependent(String beanName, String dependentBeanName) {
return isDependent(beanName, dependentBeanName, null);
}
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
String canonicalName = canonicalName(beanName);
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<String>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
/**
* 判断是否已经有被注册的依赖关系的bean
* @param beanName the name of the bean to check
* @return
*/
protected boolean hasDependentBean(String beanName) {
return this.dependentBeanMap.containsKey(beanName);
}
public String[] getDependentBeans(String beanName) {
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
return StringUtils.toStringArray(dependentBeans);
}
/**
* 获取所有有依赖关系的bean
* @param beanName the name of the bean to check
* @return
*/
public String[] getDependenciesForBean(String beanName) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
if (dependenciesForBean == null) {
return new String[0];
}
return dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
}
/**
* 销毁所有单例
*/
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
//将正在销毁单例这个标志符置为true
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
/**
* 销毁某个bean的单例
* @param beanName 待销毁的bean name
*/
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
/**
* 销毁bean,在销毁之前需要销毁所有跟它有依赖关系的bean
* @param beanName bean name
* @param bean 待销毁的bean instance
*/
protected void destroyBean(String beanName, DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
//销毁有依赖关系的bean
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
// Trigger destruction of contained beans...
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}
public final Object getSingletonMutex() {
return this.singletonObjects;
}
}
整个类着重实现了单例模式从注册,到使用,再到销毁这个过程,代码可读性还是很强的。
可能整个逻辑比较复杂的就是根据bean name获取该bean的实例,具体的获取步骤已经在注释中详细的给出,分哪些情况,从哪些缓存中取,在此不做更详细的赘述了。