概述
这个class是个比较关键的类,它也是后面的完成工厂所继承的顶级class,主要就是实现别名注册接口和单例注册接口,从而提供这些服务。
属性
//抑制异常最多100个
private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;
//一级缓存,缓存beanName和bean实例
private final Map singletonObjects = new ConcurrentHashMap<>(256);
//二级缓存,缓存beanName和单例工厂
private final Map> singletonFactories = new HashMap<>(16);
//三级缓存,缓存beanName和提前暴露的bean实例
private final Map earlySingletonObjects = new HashMap<>(16);
//已注册的单例集合
private final Set registeredSingletons = new LinkedHashSet<>(256);
//当前正在创建的单例名字集合
private final Set singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//创建检测时需要排除的bean的名字集合
private final Set inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//已抑制的异常的集合
@Nullable
private Set suppressedExceptions;
//标识是否当前处于销毁单例过程
private boolean singletonsCurrentlyInDestruction = false;
//可销毁的bean实例
private final Map disposableBeans = new LinkedHashMap<>();
//bean和它包含的bean之间的map
private final Map> containedBeanMap = new ConcurrentHashMap<>(16);
//bean和依赖它的bean之间的map
private final Map> dependentBeanMap = new ConcurrentHashMap<>(64);
//bean和它依赖的bean之间的map,注意与上面的区别
private final Map> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
方法
registerSingleton
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
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);
}
}
下面是真正做事情的方法,它会在一级缓存里面添加数据,其他缓存统统删除
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
这里为何要用俩个synchronized关键字?最外层的保留不就行了?
getSingleton
返回一个单例,注意这里有个参数是否允许提前暴露一个实例化完成,但初始化未完成的bean,之所以要这样设计是为了解决循环引用问题,这个问题很简单,就是beanA依赖beanB,beanB依赖beanA如果每个都去等待另一个bean创建完成就会陷入死循环中。
这个方法实现了接口中的定义,值得注意的是还有个同名重载方法,并不是直接实现接口。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
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();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
同名重载方法
这个方法并没有提前暴露引用,主要就是在找不到对应单例的情况下创建单例,并放到缓存中
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException}
//创建前检查
beforeSingletonCreation(beanName);
boolean newSingleton = false;
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) {
throw ex;
}
finally {
//创建后检查
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
值得注意的是有个创建前检测和创建后检测
protected void beforeSingletonCreation(String beanName) {
//创建检测排除表中没有包含当前beanName,添加到单例创建列表失败就意味着继续创建意味着数据不一致,所以抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
protected void afterSingletonCreation(String beanName) {
//创建检测排除表中没有包含当前beanName,从单例创建列表移除失败就意味着数据将不一致,所以抛出异常
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
removeSingleton
没什么好说的,相关缓存中全部移除
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
isDependent
这里的alreadySeen用来记录已经查找过的beanName,因为要判断bean之间的依赖关系,不仅仅是查看这个bean的直接依赖还要去这个bean的依赖的依赖去查找,所以需要递归,而递归的时候如果某个beanName已经被验证过,就会跳过,所以才需要这个alreadySeen来记录校验过得beanName
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set alreadySeen) {
//这里是干嘛用的?
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
//获取实名
String canonicalName = canonicalName(beanName);
Set 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<>();
}
alreadySeen.add(beanName);
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
destroyBean
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
Set containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
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>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
Map.Entry> entry = it.next();
Set dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
}
销毁单例的流程
1.从依赖表中删除当前bean,依赖表是对象与其依赖对象的关系表
2.遍历bean依赖的对象,挨个调用销毁单例方法
3.如果是可销毁对象,就调用其对象销毁方法
4.遍历bean的内部bean对象,挨个调用销毁单例方法
5.迭代整个依赖表,为什么?因为要从依赖表中找到曾经依赖过当前bean的对象,从它们的依赖对象集合中删除这个bean,从而完成当前bean的缓存清理工作
6.从被依赖表中移除当前bean,不需要遍历!因为这个map本就是维护bean和依赖其的对象的关系表