首先,我们想要知道一个接口有哪些功能,就必须要看这个接口的源代码,在idea中,选中这个接口Ctrl+F12,来查看这个接口里面有哪些方法:
表面上来看,功能其实很少,查看源码及其方法、功能
package org.springframework.beans.factory; | |
import org.springframework.beans.BeansException; | |
import org.springframework.core.ResolvableType; | |
import org.springframework.lang.Nullable; | |
public interface BeanFactory { | |
// factoryBean 的转义标识符。 | |
String FACTORY_BEAN_PREFIX = "&"; | |
// 根据 name 从容器中拿对应的 bean。 | |
Object getBean(String name) throws BeansException; | |
// 根据 name 和 type 从容器中拿对应的 bean,要对 bean 的类型做校验。 | |
<T> T getBean(String name, Class<T> requiredType) throws BeansException; | |
// 在容器中能否找到与 name 匹配的 bean 或者 beanDefinition。 | |
boolean containsBean(String name); | |
// 判断 name 对对应的 bean 是不是 单例。 | |
boolean isSingleton(String name) throws NoSuchBeanDefinitionException; | |
boolean isPrototype(String name) throws NoSuchBeanDefinitionException; | |
// 判断 name 对应的 bean 与指定的类型是否匹配。 | |
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws | |
NoSuchBeanDefinitionException; | |
boolean isTypeMatch(String name, Class<?> typeToMatch)throws | |
NoSuchBeanDefinitionException; | |
//根据 name 获取对应的 bean 的类型。 | |
Class<?> getType(String name) throws NoSuchBeanDefinitionException; | |
// 根据 name 获取对应 bean 的 别名。 | |
String[] getAliases(String name); | |
} |
BeanFactory表面上来看只有 getBean有点用,实际上我们不能只光看它接口,还要看它的实现类,实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供
- HierarchicalBeanFactory:提供父容器的访问功能
- ListableBeanFactory:提供了批量获取Bean的方法
- AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理
- ConfigurableBeanFactory:主要单例bean的注册,生成实例,以及统计单例bean
- ConfigurableListableBeanFactory:继承了上述的所有接口,增加了其他功能:比如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系, bean如何销毁…
- 实现类DefaultListableBeanFactory:实现了ConfigurableListableBeanFactory,注册BeanDefinition,实现上述BeanFactory所有功能
来看一下DefaultListableBeanFactory的继承关系图:
可以看到,BeanFactory只是它实现的很少一部分,除了BeanFactory提供的getBean,还有其他方法,所以我们不能光看一个接口,还要看它的具体实现类
在这里我们就只看它的DefaultSingletonBeanRegistry接口中的单例对象,这个为大家比较熟悉的,来看源码:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { | |
/** Maximum number of suppressed exceptions to preserve. */ | |
/** | |
* 抑制异常数量最大值 | |
*/ | |
private static final int SUPPRESSED_EXCEPTIONS_LIMIT =; | |
/** Cache of singleton objects: bean name to bean instance. */ | |
/** | |
* 一级缓存 这个就是我们大名鼎鼎的单例缓存池 用于保存我们所有的单实例bean | |
*/ | |
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(); | |
/** Cache of singleton factories: bean name to ObjectFactory. */ | |
/** | |
* 三级缓存 该map用户缓存 key为 beanName value 为ObjectFactory(包装为早期对象) | |
*/ | |
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(); | |
/** Cache of early singleton objects: bean name to bean instance. */ | |
/** | |
* 二级缓存 ,用户缓存我们的key为beanName value是我们的早期对象(对象属性还没有来得及进行赋值) | |
*/ | |
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(); | |
/** Set of registered singletons, containing the bean names in registration order. */ | |
/** | |
* 已注册的单例名称set | |
*/ | |
private final Set<String> registeredSingletons = new LinkedHashSet<>(); | |
/** Names of beans that are currently in creation. */ | |
/** | |
* 该集合用于缓存当前正在创建bean的名称 | |
*/ | |
private final Set<String> singletonsCurrentlyInCreation = | |
Collections.newSetFromMap(new ConcurrentHashMap<>()); | |
/** Names of beans currently excluded from in creation checks. */ | |
/** | |
* 排除当前创建检查的 | |
*/ | |
private final Set<String> inCreationCheckExclusions = | |
Collections.newSetFromMap(new ConcurrentHashMap<>()); | |
/** | |
* Collection of suppressed Exceptions, available for associating related causes. | |
*/ | |
/**抑制异常的集合,可用于关联相关原因*/ | |
private Set<Exception> suppressedExceptions; | |
/** Flag that indicates whether we're currently within destroySingletons. */ | |
/** | |
* 指示我们当前是否在 destroySingletons 中的标志。 | |
*/ | |
private boolean singletonsCurrentlyInDestruction = false; | |
/** Disposable bean instances: bean name to disposable instance. */ | |
/** | |
* 用于缓存记录实现了DisposableBean 接口的实例 | |
*/ | |
private final Map<String, Object> disposableBeans = new LinkedHashMap<>(); | |
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */ | |
/** | |
* 缓存bean的属性关系的映射<service,<aDao,bDa>> | |
*/ | |
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(); | |
/** Map between dependent bean names: bean name to Set of dependent bean names. */ | |
/** | |
* 保存的是依赖 beanName 之间的映射关系:beanName - > 依赖 beanName 的集合 | |
*/ | |
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(); | |
/** Map between depending bean names: bean name to Set of bean names for the bean's dependencies. */ | |
/** | |
* 保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合 | |
*/ | |
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(); | |
/** | |
* 注册单例Bean | |
* | |
* @param beanName the name of the bean | |
* @param singletonObject the existing singleton object | |
* @throws IllegalStateException | |
*/ | |
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { | |
//断言beanName是否为空 | |
Assert.notNull(beanName, "Bean name must not be null"); | |
//断言singletonObject是否为空 | |
Assert.notNull(singletonObject, "Singleton object must not be null"); | |
synchronized (this.singletonObjects) { | |
//从一级缓存中通过beanName拿取Bean | |
Object oldObject = this.singletonObjects.get(beanName); | |
//一级缓存中存在了,抛出IllegalStateException | |
if (oldObject != null) { | |
throw new IllegalStateException("Could not register object [" + singletonObject + | |
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound"); | |
} | |
//如果不存在,将singletonObject添加到一级缓存 | |
addSingleton(beanName, singletonObject); | |
} | |
} | |
/** | |
* Add the given singleton object to the singleton cache of this factory. | |
* <p>To be called for eager registration of singletons. | |
* 把对象加入到单例缓存池中(所谓的一级缓存 并且考虑循环依赖和正常情况下,移除二三级缓存) | |
* | |
* @param beanName the name of the bean | |
* @param singletonObject the singleton object | |
*/ | |
protected void addSingleton(String beanName, Object singletonObject) { | |
synchronized (this.singletonObjects) { | |
//将singletonObject添加到一级缓存中,同时移除二级、三级缓存、并标记当前Bean已注册 | |
this.singletonObjects.put(beanName, singletonObject); | |
//移除三级缓存 | |
this.singletonFactories.remove(beanName); | |
//移除二级缓存 | |
this.earlySingletonObjects.remove(beanName); | |
//标记当前Bean已被注册 | |
this.registeredSingletons.add(beanName); | |
} | |
} | |
/** | |
* 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. | |
* 该方法用于把早期对象包装成一个ObjectFactory 暴露到三级缓存中 用于将解决循环依赖... | |
* | |
* @param beanName the name of the bean | |
* @param singletonFactory the factory for the singleton object | |
*/ | |
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { | |
//断言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); | |
//标记当前Bean已经被注册过 | |
this.registeredSingletons.add(beanName); | |
} | |
} | |
} | |
/** | |
* 该方法是一个空壳方法 | |
* | |
* @param beanName the name of the bean to look for | |
* @return 缓存中的对象(有可能是一个单例完整对象, 也有可能是一个早期对象 ( 用于解决循环依赖)) | |
*/ | |
public Object getSingleton(String beanName) { | |
//在这里 系统一般是允许早期对象引用的 allowEarlyReference通过这个参数可以控制解决循环依赖 | |
return getSingleton(beanName, true); | |
} | |
/** | |
* 在网上很多很多写源码的大佬或者是<spring源码深度解析>一书上,也没有说清楚为啥要使用三级缓存(二级缓存可不可以能够 | |
* 解决) 答案是:可以, 但是没有很好的扩展性为啥这么说....... | |
* 原因: 获取三级缓存-----getEarlyBeanReference()经过一系列的后置处理来给我们早期对象进行特殊化处理 | |
* //从三级缓存中获取包装对象的时候 ,他会经过一次后置处理器的处理对我们早期对象的bean进行 | |
* 特殊化处理,但是spring的原生后置处理器没有经过处理,而是留给了我们程序员进行扩展 | |
* singletonObject = singletonFactory.getObject(); | |
* 把三级缓存移植到二级缓存中 | |
* this.earlySingletonObjects.put(beanName, singletonObject); | |
* //删除三级缓存中的之 | |
* this.singletonFactories.remove(beanName); | |
* | |
* @param beanName bean的名称 | |
* @param allowEarlyReference 是否允许暴露早期对象 通过该参数可以控制是否能够解决循环依赖的. | |
* @return 这里可能返回一个null(IOC容器加载单实例bean的时候,第一次进来是返回null) | |
* 也有可能返回一个单例对象(IOC容器加载了单实例了,第二次来获取当前的Bean) | |
* 也可能返回一个早期对象(用于解决循环依赖问题) | |
*/ | |
protected Object getSingleton(String beanName, boolean allowEarlyReference) { | |
// Quick check for existing instance without full singleton lock | |
/** | |
* 第一步:我们尝试去一级缓存(单例缓存池中去获取对象,一般情况从该map中获取的对象是直接可以使用的) | |
* IOC容器初始化加载单实例bean的时候第一次进来的时候 该map中一般返回空 | |
*/ | |
Object singletonObject = this.singletonObjects.get(beanName); | |
//如果一级缓存为空,并且标记正在创建 | |
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { | |
/** | |
* 尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象) | |
* 何为早期对象:就是bean刚刚调用了构造方法,还来不及给bean的属性进行赋值的对象(纯净态) | |
* 就是早期对象 | |
*/ | |
singletonObject = this.earlySingletonObjects.get(beanName); | |
/** | |
* 二级缓存中也没有获取到对象,allowEarlyReference为true(参数是有上一个方法传递进来的true) | |
*/ | |
if (singletonObject == null && allowEarlyReference) { | |
synchronized (this.singletonObjects) { | |
// Consistent creation of early reference within full singleton lock | |
/** | |
* 再次尝试从一级缓存中去拿,如果还是没拿到则尝试去二级缓存中拿 | |
*/ | |
singletonObject = this.singletonObjects.get(beanName); | |
//一级缓存中没拿到 | |
if (singletonObject == null) { | |
//尝试从二级缓存中去拿 | |
singletonObject = this.earlySingletonObjects.get(beanName); | |
//二级缓存还是空 | |
if (singletonObject == null) { | |
/** | |
* 直接从三级缓存中获取 ObjectFactory对象 这个对接就是用来解决循环依赖的关键所在 | |
* 在ioc后期的过程中,当bean调用了构造方法的时候,把早期对象包裹成一个ObjectFactory | |
* 暴露到三级缓存中 | |
*/ | |
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); | |
//三级缓存中获取的对象不为空 | |
if (singletonFactory != null) { | |
/** | |
* 在这里通过暴露的ObjectFactory 包装对象中,通过调用他的getObject()来获取我们的早期对象 | |
* 在这个环节中会调用到 getEarlyBeanReference()来进行后置处理 | |
*/ | |
singletonObject = singletonFactory.getObject(); | |
//把早期对象放置在二级缓存, | |
this.earlySingletonObjects.put(beanName, singletonObject); | |
//ObjectFactory 包装对象从三级缓存中删除掉 | |
this.singletonFactories.remove(beanName); | |
} | |
} | |
} | |
} | |
} | |
} | |
//返回这个Bean | |
return singletonObject; | |
} | |
/** | |
* Return the (raw) singleton object registered under the given name, | |
* creating and registering a new one if none registered yet. | |
* 获取单例对象(该流程用于触发构建bean) | |
* | |
* @param beanName the name of the bean | |
* @param singletonFactory the ObjectFactory to lazily create the singleton | |
* with, if necessary | |
* @return the registered singleton object | |
*/ | |
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { | |
//断言beanName不为空 | |
Assert.notNull(beanName, "Bean name must not be null"); | |
//同步加锁 | |
synchronized (this.singletonObjects) { | |
//尝试从一级缓存池中获取对象 | |
Object singletonObject = this.singletonObjects.get(beanName); | |
//从一级缓存中没拿到 | |
if (singletonObject == null) { | |
//当前是否是正在销毁,是的话抛出BeanCreationNotAllowedException异常 | |
if (this.singletonsCurrentlyInDestruction) { | |
throw new BeanCreationNotAllowedException(beanName, | |
"Singleton bean creation not allowed while singletons of this factory are in destruction " + | |
"(Do not request a bean from a BeanFactory in a destroy method implementation!)"); | |
} | |
//判断是否已启用Debug调试模式 | |
if (logger.isDebugEnabled()) { | |
logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); | |
} | |
/** | |
* 标记当前的bean马上就要被创建了 | |
* singletonsCurrentlyInCreation 在这里会把beanName加入进来,若第二次循环依赖(构造器注入会抛出异常) | |
*/ | |
beforeSingletonCreation(beanName); | |
//标记是否为新创建的单例Bean | |
boolean newSingleton = false; | |
//标记是否记录抑制异常 | |
boolean recordSuppressedExceptions = (this.suppressedExceptions == null); | |
//如果为空,创建抑制异常集合 | |
if (recordSuppressedExceptions) { | |
this.suppressedExceptions = new LinkedHashSet<>(); | |
} | |
try { | |
// 初始化 bean | |
// 这个过程其实是调用 createBean() 方法 | |
singletonObject = singletonFactory.getObject(); | |
//标记这个Bean是新创建的 | |
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; | |
} | |
//后置处理 | |
//主要做的事情就是把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除 | |
afterSingletonCreation(beanName); | |
} | |
//是新建的单例Bean,添加到一级缓存中去 | |
if (newSingleton) { | |
addSingleton(beanName, singletonObject); | |
} | |
} | |
//返回单例Bean | |
return singletonObject; | |
} | |
} | |
/** | |
* Register an exception that happened to get suppressed during the creation of a | |
* singleton bean instance, e.g. a temporary circular reference resolution problem. | |
* <p>The default implementation preserves any given exception in this registry's | |
* collection of suppressed exceptions, up to a limit of exceptions, adding | |
* them as related causes to an eventual top-level {@link BeanCreationException}. | |
* 注册在创建单例 bean 实例期间碰巧被抑制的异常,例如一个临时的循环引用解析问题。 | |
* | |
* @param ex the Exception to register | |
* @see BeanCreationException#getRelatedCauses() | |
*/ | |
protected void onSuppressedException(Exception ex) { | |
synchronized (this.singletonObjects) { | |
//抑制异常集合不为空,且小于SUPPRESSED_EXCEPTIONS_LIMIT最大限制 | |
if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) { | |
//向抑制集合中添加异常 | |
this.suppressedExceptions.add(ex); | |
} | |
} | |
} | |
/** | |
* Remove the bean with the given name from the singleton cache of this factory, | |
* to be able to clean up eager registration of a singleton if creation failed. | |
* 从该工厂的单例缓存中删除bean ,以便能够在创建失败时清除单例的急切注册。 | |
* | |
* @param beanName the name of the bean | |
* @see #getSingletonMutex() | |
*/ | |
protected void removeSingleton(String beanName) { | |
//同步加锁 | |
synchronized (this.singletonObjects) { | |
//从一级缓存中移除 | |
this.singletonObjects.remove(beanName); | |
//从三级缓存中移除 | |
this.singletonFactories.remove(beanName); | |
//从二级缓存中移除 | |
this.earlySingletonObjects.remove(beanName); | |
//从Bean注册标记集合中移除 | |
this.registeredSingletons.remove(beanName); | |
} | |
} | |
/** | |
* 一级缓存中是否存在该Bean | |
* | |
* @param beanName the name of the bean to look for | |
* @return | |
*/ | |
public boolean containsSingleton(String beanName) { | |
//判断一级缓存中是否存在该Bean | |
return this.singletonObjects.containsKey(beanName); | |
} | |
/** | |
* 获取已注册的单例Bean名字的集合 | |
* | |
* @return | |
*/ | |
public String[] getSingletonNames() { | |
synchronized (this.singletonObjects) { | |
//获取已注册的单例Bean名字的集合 | |
return StringUtils.toStringArray(this.registeredSingletons); | |
} | |
} | |
/** | |
* 获取已注册单例Bean实例的个数 | |
* | |
* @return | |
*/ | |
public int getSingletonCount() { | |
synchronized (this.singletonObjects) { | |
//获取已注册单例Bean实例的个数 | |
return this.registeredSingletons.size(); | |
} | |
} | |
/** | |
* 标记当前Bean正在创建,主要解决循环依赖 | |
* | |
* @param beanName Bean名字 | |
* @param inCreation 是否已标记 | |
*/ | |
public void setCurrentlyInCreation(String beanName, boolean inCreation) { | |
//断言Bean不为空 | |
Assert.notNull(beanName, "Bean name must not be null"); | |
//如果未标记,将beanName加到inCreationCheckExclusions集合中,已标记则移除 | |
if (!inCreation) { | |
this.inCreationCheckExclusions.add(beanName); | |
} else { | |
this.inCreationCheckExclusions.remove(beanName); | |
} | |
} | |
/** | |
* 返回当前Bean是否是正在创建 | |
* | |
* @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实际上是否在创建中 | |
* | |
* @param beanName | |
* @return | |
*/ | |
protected boolean isActuallyInCreation(String beanName) { | |
return isSingletonCurrentlyInCreation(beanName); | |
} | |
/** | |
* Return whether the specified singleton bean is currently in creation | |
* (within the entire factory). | |
* 返回指定的单例 bean 当前是否正在创建中 | |
* | |
* @param beanName the name of the bean | |
*/ | |
public boolean isSingletonCurrentlyInCreation(String beanName) { | |
return this.singletonsCurrentlyInCreation.contains(beanName); | |
} | |
/** | |
* Callback before singleton creation. | |
* <p>The default implementation register the singleton as currently in creation. | |
* 单例Bean创建前回调方法,默认实现将单例注册为当前正在创建中 | |
* | |
* @param beanName the name of the singleton about to be created | |
* @see #isSingletonCurrentlyInCreation | |
*/ | |
protected void beforeSingletonCreation(String beanName) { | |
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) { | |
throw new BeanCurrentlyInCreationException(beanName); | |
} | |
} | |
/** | |
* Callback after singleton creation. | |
* <p>The default implementation marks the singleton as not in creation anymore. | |
* 创建单例后回调。 默认实现将单例标记为不再创建。 | |
* | |
* @param beanName the name of the singleton that has been created | |
* @see #isSingletonCurrentlyInCreation | |
*/ | |
protected void afterSingletonCreation(String beanName) { | |
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) { | |
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation"); | |
} | |
} | |
/** | |
* Add the given bean to the list of disposable beans in this registry. | |
* <p>Disposable beans usually correspond to registered singletons, | |
* matching the bean name but potentially being a different instance | |
* (for example, a DisposableBean adapter for a singleton that does not | |
* naturally implement Spring's DisposableBean interface). | |
* 将给定的 bean 添加到此注册表中的一次性 bean 列表中。 一次性 bean 通常对应于已注册的单例, | |
* 与 bean 名称匹配,但可能是不同的实例(例如,单例的 DisposableBean 适配器不自然实现 Spring 的 DisposableBean 接口)。 | |
* | |
* @param beanName the name of the bean | |
* @param bean the bean instance | |
*/ | |
public void registerDisposableBean(String beanName, DisposableBean bean) { | |
synchronized (this.disposableBeans) { | |
this.disposableBeans.put(beanName, bean); | |
} | |
} | |
/** | |
* Register a containment relationship between two beans, | |
* e.g. between an inner bean and its containing outer bean. | |
* <p>Also registers the containing bean as dependent on the contained bean | |
* in terms of destruction order. | |
* 注册两个 bean 之间的包含关系,例如在内部 bean 和包含它的外部 bean 之间。还根据销毁顺序将包含的 bean 注册为依赖于所包含的 bean。 | |
* | |
* @param containedBeanName the name of the contained (inner) bean | |
* @param containingBeanName the name of the containing (outer) bean | |
* @see #registerDependentBean | |
*/ | |
public void registerContainedBean(String containedBeanName, String containingBeanName) { | |
synchronized (this.containedBeanMap) { | |
Set<String> containedBeans = | |
this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>()); | |
if (!containedBeans.add(containedBeanName)) { | |
return; | |
} | |
} | |
registerDependentBean(containedBeanName, containingBeanName); | |
} | |
/** | |
* Register a dependent bean for the given bean, | |
* to be destroyed before the given bean is destroyed. | |
* | |
* @param beanName the name of the bean | |
* @param dependentBeanName the name of the dependent bean | |
*/ | |
public void registerDependentBean(String beanName, String dependentBeanName) { | |
//获取原始的beanName | |
String canonicalName = canonicalName(beanName); | |
// 添加 <canonicalName, <dependentBeanName>> 到 dependentBeanMap 中 | |
synchronized (this.dependentBeanMap) { | |
Set<String> dependentBeans = | |
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>()); | |
if (!dependentBeans.add(dependentBeanName)) { | |
return; | |
} | |
} | |
// 添加 <dependentBeanName, <canonicalName>> 到 dependenciesForBeanMap 中 | |
synchronized (this.dependenciesForBeanMap) { | |
Set<String> dependenciesForBean = | |
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>()); | |
dependenciesForBean.add(canonicalName); | |
} | |
} | |
/** | |
* Determine whether the specified dependent bean has been registered as | |
* dependent on the given bean or on any of its transitive dependencies. | |
* 判断指定的 bean 是否依赖于 dependentBeanName 。 | |
* | |
* @param beanName the name of the bean to check | |
* @param dependentBeanName the name of the dependent bean | |
* @since.0 | |
*/ | |
//判断指定的 bean 是否依赖于 dependentBeanName | |
protected boolean isDependent(String beanName, String dependentBeanName) { | |
synchronized (this.dependentBeanMap) { | |
return isDependent(beanName, dependentBeanName, null); | |
} | |
} | |
//判断指定的 bean 是否依赖于 dependentBeanName | |
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) { | |
// alreadySeen 已经检测的依赖 bean | |
if (alreadySeen != null && alreadySeen.contains(beanName)) { | |
return false; | |
} | |
// 获取原始 beanName | |
String canonicalName = canonicalName(beanName); | |
//获取创建当前bean 所依赖的bean的名称集合 | |
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName); | |
//不依赖任何前置Bean 直接返回 | |
if (dependentBeans == null) { | |
return false; | |
} | |
// 存在,则证明存在已经注册的依赖 | |
if (dependentBeans.contains(dependentBeanName)) { | |
return true; | |
} | |
// 递归检测依赖 | |
for (String transitiveDependency : dependentBeans) { | |
if (alreadySeen == null) { | |
alreadySeen = new HashSet<>(); | |
} | |
// 添加到 alreadySeen 中 | |
alreadySeen.add(beanName); | |
//递归检查依赖 | |
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Determine whether a dependent bean has been registered for the given name. | |
* | |
* @param beanName the name of the bean to check | |
*/ | |
//判断beanName是否注册为依赖Bean | |
protected boolean hasDependentBean(String beanName) { | |
return this.dependentBeanMap.containsKey(beanName); | |
} | |
/** | |
* Return the names of all beans which depend on the specified bean, if any. | |
* 返回Bean所依赖的所有Bean集合 | |
* | |
* @param beanName the name of the bean | |
* @return the array of dependent bean names, or an empty array if none | |
*/ | |
public String[] getDependentBeans(String beanName) { | |
//Bean依赖集合 | |
Set<String> dependentBeans = this.dependentBeanMap.get(beanName); | |
if (dependentBeans == null) { | |
return new String[]; | |
} | |
synchronized (this.dependentBeanMap) { | |
return StringUtils.toStringArray(dependentBeans); | |
} | |
} | |
/** | |
* Return the names of all beans that the specified bean depends on, if any. | |
* 返回Bean所依赖的所有Bean集合 | |
* | |
* @param beanName the name of the bean | |
* @return the array of names of beans which the bean depends on, | |
* or an empty array if none | |
*/ | |
public String[] getDependenciesForBean(String beanName) { | |
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName); | |
if (dependenciesForBean == null) { | |
return new String[]; | |
} | |
synchronized (this.dependenciesForBeanMap) { | |
return StringUtils.toStringArray(dependenciesForBean); | |
} | |
} | |
/** | |
* 销毁所有bean的所有信息 | |
*/ | |
public void destroySingletons() { | |
if (logger.isTraceEnabled()) { | |
logger.trace("Destroying singletons in " + this); | |
} | |
//标记为正在销毁 | |
synchronized (this.singletonObjects) { | |
this.singletonsCurrentlyInDestruction = true; | |
} | |
String[] disposableBeanNames; | |
//获取需要销毁的Bean集合 | |
synchronized (this.disposableBeans) { | |
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); | |
} | |
//循环校徽单例Bean | |
for (int i = disposableBeanNames.length -; i >= 0; i--) { | |
destroySingleton(disposableBeanNames[i]); | |
} | |
// 清空依赖和映射关系缓存 | |
this.containedBeanMap.clear(); | |
this.dependentBeanMap.clear(); | |
this.dependenciesForBeanMap.clear(); | |
// 清理Bean的一级二级三级缓存 | |
clearSingletonCache(); | |
} | |
/** | |
* Clear all cached singleton instances in this registry. | |
* 清除所有缓存的单例实例。 | |
* | |
* @since.3.15 | |
*/ | |
protected void clearSingletonCache() { | |
synchronized (this.singletonObjects) { | |
this.singletonObjects.clear(); | |
this.singletonFactories.clear(); | |
this.earlySingletonObjects.clear(); | |
this.registeredSingletons.clear(); | |
this.singletonsCurrentlyInDestruction = false; | |
} | |
} | |
/** | |
* Destroy the given bean. Delegates to {@code destroyBean} | |
* if a corresponding disposable bean instance is found. | |
* | |
* @param beanName the name of the bean | |
* @see #destroyBean | |
*/ | |
public void destroySingleton(String beanName) { | |
// Remove a registered singleton of the given name, if any. | |
//从缓存中移除当前bean的相关信息,由于不知道在哪里发生异常,所以我们把跟当前bean的所有缓存记录都清除 | |
removeSingleton(beanName); | |
// Destroy the corresponding DisposableBean instance. | |
//创建一个变量用于接受 实现了DisposableBean接口的对象变量 | |
DisposableBean disposableBean; | |
synchronized (this.disposableBeans) { | |
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName); | |
} | |
//进行bean的销毁 | |
destroyBean(beanName, disposableBean); | |
} | |
/** | |
* Destroy the given bean. Must destroy beans that depend on the given | |
* bean before the bean itself. Should not throw any exceptions. | |
* 销毁bean的依赖关系 | |
* | |
* @param beanName the name of the bean | |
* @param bean the bean instance to destroy | |
*/ | |
protected void destroyBean(String beanName, DisposableBean bean) { | |
// Trigger destruction of dependent beans first... | |
// 销毁dependentBeanMap中保存的是当前bean和依赖bean之间的映射 | |
Set<String> dependencies; | |
synchronized (this.dependentBeanMap) { | |
// Within full synchronization in order to guarantee a disconnected Set | |
//把当前创建dependon 依赖的bean从缓存中移除并且返回处理 | |
dependencies = this.dependentBeanMap.remove(beanName); | |
} | |
//如果bean依赖不为空 | |
if (dependencies != null) { | |
if (logger.isTraceEnabled()) { | |
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies); | |
} | |
//递归销毁bean | |
for (String dependentBeanName : dependencies) { | |
destroySingleton(dependentBeanName); | |
} | |
} | |
// Actually destroy the bean now... | |
//真正的调用bean的destory()方法 | |
if (bean != null) { | |
try { | |
bean.destroy(); | |
} catch (Throwable ex) { | |
if (logger.isWarnEnabled()) { | |
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex); | |
} | |
} | |
} | |
// 删除bean的属性关系的映射 | |
Set<String> 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. | |
//销毁dependentBeanMap 中 Bean的依赖 | |
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. | |
//从dependenciesForBeanMap集合移除 | |
this.dependenciesForBeanMap.remove(beanName); | |
} | |
/** | |
* Exposes the singleton mutex to subclasses and external collaborators. | |
* <p>Subclasses should synchronize on the given Object if they perform | |
* any sort of extended singleton creation phase. In particular, subclasses | |
* should <i>not</i> have their own mutexes involved in singleton creation, | |
* to avoid the potential for deadlocks in lazy-init situations. | |
*/ | |
/** | |
* 将单例互斥体暴露给子类和外部合作者。 如果子类执行任何类型的扩展单例创建阶段, | |
* 它们应该在给定的对象上同步。特别是子类不应该在单例创建中使用它们自己的互斥锁, | |
* 以避免在惰性初始化情况下潜在的死锁。 | |
*/ | |
public final Object getSingletonMutex() { | |
return this.singletonObjects; | |
} | |
} |
它的方法大多为私有的,可以通过debug和反射,在这里我们通过反射来获取私有的成员变量:
// DefaultSingletonBeanRegistry类管理所有的单例对象 | |
//获取所有的私有成员变量 | |
Field singletonObjects = | |
DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects"); | |
//允许可以访问私有成员变量 | |
singletonObjects.setAccessible(true); | |
//通过反射获取 | |
//获取beanFactory | |
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); | |
//反射调用,获取beanFactory的属性 | |
Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory); | |
//过滤,获取component相关的 | |
map.entrySet().stream().filter(e -> e.getKey().startsWith("component")) | |
.forEach(e -> { | |
System.out.println(e.getKey() + "=" + e.getValue()); | |
}); |
总结:
BeanFactory 能干点啥?
- 表面上只有 getBean
- 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能,都由它的实现类提供
- 例子中通过反射查看了它的成员变量 singletonObjects,内部包含了所有的单例 bean