DefaultSingletonBeanRegistry
DefaultSingletonBeanRegistry
这是 DefaultSingletonBeanRegistry 类的体系结构,由一个类一个责任的原则:
AliasRegistry : 提供别名注册的接口
SimpleAliasRegistry : 它简单地实现了AliasRegistry接口。
SingletonBeanRegistry : 提供单例bean注册的接口
DefaultSingletonBeanRegistry :它继承SimpleAliasRegistry类和实现了SingletonBeanRegistry接口,因此这个类可以有别名注册的功能和单例bean注册的功能,并且他还支持注册DisposableBean实例;它依赖ObjectFactory接口和DisposableBean接口(关闭注册表时调用到了destroy方法)。
ObjectFactory : 这个接口通常用于封装一个通用的工厂,它只有一个方法getObject() ,它调用getObject()方法返回一个新的实例,一些在每次调用的目标对象(原型).
DisposableBean : 接口实现为beans要破坏释放资源。它也只有一个方法destroy(),由一个破坏一个singleton的BeanFactory调用。
/**
* 共享bean实例的通用注册表,实现了SingletonBeanRegistry. 允许注册表中注册的单例应该被所有调用者共享,通过bean名称获得。
*
* 还支持登记的DisposableBean实例,(这可能会或不能正确的注册单例),关闭注册表时destroyed.
* 可以注册bean之间的依赖关系,执行适当的关闭顺序。
*
*
* 这个类主要用作基类的BeanFactory实现, 提供基本的管理
* singleton bean 实例功能。
*
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
SingletonBeanRegistry {
// null 单例对象的内部标记:用作并发 Map(不支持null值)的标记值
protected static final Object NULL_OBJECT = new Object();
// 日志用来记录子类
protected final Log logger = LogFactory.getLog(getClass());
// singleton 对象的缓存:bean name --> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
// singleton 的工厂对象的缓存:bean name --> ObjectFactory
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>();
// singletonFactory 制造出来的 singleton 的缓存:bean name --> bean instance
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>();
//以上三个缓存是这个类存放单例 bean 的主要 Map
// 就是单例注册表
private final Set<String> registeredSingletons = new LinkedHashSet<String>(16);
// 目前正在创建中的单例 bean 的名称的集合
private final Set<String> singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet<String>());
// 当前在创建检查中排除的 bean 的名称
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
// 存放异常出现的相关的原因的集合
private Set<Exception> suppressedExceptions;
// 标志,指示我们目前是否在销毁单例中
private boolean singletonsCurrentlyInDestruction = false;
// 存放一次性bean的缓存
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
// 外部 bean 与其所有内部 bean 集合:外部 bean name --> 外部 bean 所包含的内部 bean 集合
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>();
// 依赖这个 bean 的所有 bean 集合(依赖我的):bean name --> 依赖这个 bean 的所有 bean 集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>();
// 这个 bean 依赖的所有 bean 集合(我依赖的) :bean name --> bean 依赖的所有 bean 集合
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>();
// 以上四个 map 集合都和 bean 的销毁有关
// SingletonBeanRegistry 接口的 registerSingleton 方法的实现
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);
//如果 singletonObjects 缓存找到有指定名称为 beanName 的对象,则表示该了bean 已经注册
if (oldObject != null) {
throw new IllegalStateException("Could not register object ["
+ singletonObject + "] under bean name '" + beanName
+ "': there is already object [" + oldObject
+ "] bound");
}
//若该名称没被占用,真正的注册操作在这里实现
addSingleton(beanName, singletonObject);
}
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 因为singletonObjects类型是 ConcurrentHashMap,并发Map不支持空值作为标志值,所以用NULL_OBJECT来代替
this.singletonObjects.put(beanName,
(singletonObject != null ? singletonObject : NULL_OBJECT));
// singletonFactories、earlySingletonObjects 解决创建 singletonObject 的过程中的循环依赖用的
// bean 创建完成后就没用的,需要销毁
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
// beanName放进单例注册表中
this.registeredSingletons.add(beanName);
}
}
// 添加名称为 beanName 的 singletonFactory 对象
protected void addSingletonFactory(String beanName,
ObjectFactory singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// 同理,bean 如果已经创建完成,就没有必要进行这步操作了
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
// SingletonBeanRegistry 接口的 getSingleton 方法的实现
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
/**
* 获取 bean 的单例
* @param beanName
* @param allowEarlyReference 是否允许循环引用
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// singletonObject = nul 说明 bean 还未创建或正在创建
// 如果 isSingletonCurrentlyInCreation(beanName) = true,说明出现了循环引用
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 显然 earlySingletonObjects、singletonFactories 是不能共存的
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
/**
* 真正的根据 ObjectFactory 创建 singletonObject 对象了
* @param beanName
* @param singletonFactory 创建 singletonObject 对象的工厂对象
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
//1. 如果 singletonObject 还没有被创建,那就开始创建吧
if (singletonObject == null) {
//2. 如果 beanName 正在被销毁,那还创建个啥,直接抛出异常就好
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 + "'");
}
//3. 单例对象创建前的回调,一个重要的工作就是将该 bean 打上正在创建的标记
beforeSingletonCreation(beanName);
// beanName 创建成功与否的一个标记
boolean newSingleton = false;
// 判断存储异常相关原因的集合是否已存在,不存在就创建一个
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//4. 好了,创建 singletonObject
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
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;
}
//5. 单例对象创建后的回调,一个重要的工作就是将该 bean 正在创建的标记销毁
afterSingletonCreation(beanName);
}
//6. beanName 创建成功,注册创建后的单例
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
// 注册 singeton bean 实例创建过程中的异常
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
}
// 销毁 beanName
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
// singletonBeanRegistry 接口的 containsSingleton 方法实现
public boolean containsSingleton(String beanName) {
return (this.singletonObjects.containsKey(beanName));
}
// singletonBeanRegistry 接口的 getSingletonNames 方法实现
public String[] getSingletonNames() {
// 对 singletonObjects 加锁,可能是为了防止 registeredSingletons 和 singletonObjects 出现不一致的问题
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
// singletonBeanRegistry 接口的 getSingletonCount 方法实现
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
}
// 将正在创建的 beanName 从 inCreationCheckExclusions 集合删除,已创建完成的加入 inCreationCheckExclusions
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);
}
}
public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
}
protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
}
// 返回 beanName 是否正在创建,即出现了循环引用
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
// 单例对象创建前的回调
// 创建前 singletonsCurrentlyInCreation 注册该 beanName,如果已经添加则会抛出异常
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
// 单例对象创建后的回调
// 创建后 singletonsCurrentlyInCreation 移除该 beanName,如果该 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");
}
}
// 一次性 bean 注册,存放在 disponsableBeans 集合中
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
}
/**
* 注册两个 bean 之间的控制关系
* @param containedBeanName the name of the contained (inner) bean
* @param containingBeanName the name of the containing (outer) bean
*/
public void registerContainedBean(String containedBeanName, String containingBeanName) {
// 先做一个简单的判断,避免使用 synchronized 关键字
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans != null && containedBeans.contains(containedBeanName)) {
return;
}
synchronized (this.containedBeanMap) {
containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans == null) {
containedBeans = new LinkedHashSet<String>(8);
this.containedBeanMap.put(containingBeanName, containedBeans);
}
containedBeans.add(containedBeanName);
}
// 紧接着调用注册内部 bean 和外部 bean 的依赖关系的方法
registerDependentBean(containedBeanName, containingBeanName);
}
/**
* 注册给定bean的一个依赖bean,给定的bean销毁之前被销毁。
*
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// 调用 SimpleAliasRegistry 的 canonicalName 方法,这方法是将参数 beanName 当做别名寻找到注册名,并依此递归
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// 注册依赖 beanName 的集合,毫无疑问 containingBeanName 依赖 containedBeanName
// 换句话说,依赖 containedBeanName 的集合中包括 containingBeanName
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
// 注册 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);
}
}
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;
}
// 确定是否还存在名为 beanName 的被依赖关系
protected boolean hasDependentBean(String beanName) {
return this.dependentBeanMap.containsKey(beanName);
}
// 返回依赖于指定的bean的所有bean的名称,如果有的话。(依赖我的)
public String[] getDependentBeans(String beanName) {
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
return StringUtils.toStringArray(dependentBeans);
}
// 返回指定的 bean 依赖于所有的 bean 的名称,如果有的话。(我依赖的)
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);
}
// 单例销毁标志开始
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
// 销毁 disponsableBeans 缓存中所有单例 bean
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;
}
}
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);
}
// 真正的销毁 beanName
// 毫无疑问,销毁该 beanName 之前要将依赖这个 beanName 的所有 bean 都销毁
protected void destroyBean(String beanName, DisposableBean bean) {
//1. 先销毁依赖这个 beanName 的所有实例
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
//2. 真正销毁该 beanName
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
}
//3. 销毁该 beanName 所包含的子 containedBean
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
}
//4. 从其它 bean 的依赖 bean 集合中删除已销毁的 beanName
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();
}
}
}
//5. 最后从 dependenciesForBeanMap 缓存中移除要销毁的 bean
this.dependenciesForBeanMap.remove(beanName);
}
// 将所有的单例暴露给子类和外部
protected final Object getSingletonMutex() {
return this.singletonObjects;
}
}
DefaultSingletonBeanRegistry的更多相关文章
- 一则spring容器启动死锁问题(DefaultListableBeanFactory/DefaultSingletonBeanRegistry)
线上发现一个问题,应用在启动时会卡死,log上并没有什么异常输出,初判应该是死锁问题. 抓现场的thread dump文件, 确实是有两个线程有deadlock问题. 线程一 "HSFBiz ...
- 哈哈,原来IOC容器的bean是存在DefaultSingletonBeanRegistry的一个Map类型的属性当中。
经过查看源代码发现IOC容器中的bean实例(不知道是不是所有的bean)是存储在一个DefaultSingletonBeanRegistry类实例的一个Map类型的属性当中. 下面是DefaultS ...
- Spring之25:SingletonBeanRegistry&DefaultSingletonBeanRegistry
此接口是针对Spring中的单例Bean设计的.提供了统一访问单例Bean的功能,BeanFactory可实现此接口以提供访问内部单例Bean的能力. //将对象(singletonObject)注册 ...
- DefaultSingletonBeanRegistry源码解析
DefaultSingletonBeanRegistry是SingletionBean注册器的默认实现. 来学习下DefaultSingletonBeanRegistry的源码: package or ...
- DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry
// 用于内部标记的空的单例对象(不支持null)protected static final Object NULL_OBJECT = new Object(); // 缓存单例对象根据beanNa ...
- Spring5:@Autowired注解、@Resource注解和@Service注解
什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分 ...
- The type javax.ws.rs.core.MediaType cannot be resolved. It is indirectly referenced from required .class files
看到了http://stackoverflow.com/questions/5547162/eclipse-error-indirectly-referenced-from-required-clas ...
- 再次学习 java 类的编译
做JAVA开发的都知道myeclipse, 我们在myeclipse中新建一个类,然后保存, 如何正常的话,那么在项目指定的目录(也就是项目的output目录)就会生成同名的class文件, 可是,我 ...
- Error on line -1 of document : Premature end of file. Nested exception: Premature end of file.
启动tomcat, 出现, ( 之前都是好好的... ) [lk ] ERROR [08-12 15:10:02] [main] org.springframework.web.context.Con ...
随机推荐
- python文件操作与字符编码
知识内容: 1.文件对象与文件处理流程 2.基本操作 3.上下文管理 4.文件的修改与文件内光标的移动 5.字符编码 一.文件对象与文件处理流程 1.文件对象 (1)文件分类 按文件中数据的组织形式可 ...
- UVA-755-排序
奇怪,我怎么还有一个排序题目没过 题意如下: 公司喜欢有难忘的电话号码,一个让电话号码变得难忘的方式是有一个拼读起来难忘的单词,比如,你可以呼叫University of Waterloo通过拨打难忘 ...
- 代码: 日期和时间 datepicker
bootstrap 的相关的时间插件 http://www.bootcss.com/p/bootstrap-datetimepicker/ jquery ui的日期插件 http://www.w3cs ...
- OpenCL 归约 1
▶ 照着书上的代码,写了几个一步归约的计算,只计算一步,将原数组归约到不超过 1024 个工作项 ● 代码 // kernel.cl __kernel void reduce01(__global u ...
- 18.OGNL与ValueStack(VS)-值栈入门
转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 下面我们建立struts2ognl项目来练习ognl的使用. 步骤一.搭建s ...
- Eclipse 更改Maven项目名
1. 在Eclipse 中修改项目名 没错这种方法跟你预料的一样简单,当项目已经导入到 Eclipse 之后,只需要做两个事情 1.1 改项目文件夹名称 选中项目,按 F12 ,改名. 多数人改项目名 ...
- 前端-CSS-8-浮动与清楚浮动(重点)
<!-- 浮动是css里面布局最多的一个属性 效果: 两个元素并排了,并且两个元素都能够设置宽度和高度 浮动想学好:一定要知道它的四个特性: 1.浮动的元素脱标 2.浮动的元素互相贴靠 3.浮动 ...
- apiCloud上传头像
apiCloud上传头像 1.拍照 2.从相机中选择 aui布局 <li class="aui-list-item"> <div class="aui- ...
- rem 的使用
1.填加以下代码 (function (designWidth, maxWidth) { var doc = document, win = window, docEl = doc.documentE ...
- display:inline、block、inline-block区别
display:inline.block.inline-block区别 display:block就是将元素显示为块级元素. display:inline就是将元素显示为行内元素. inline-bl ...