相关源码注释
ApplicationContext
Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释
BeanFactory
Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释
getSingleton(String,ObjectFactory)
返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象
- 如果beanName为null,抛出异常
- 使用单例对象的高速缓存Map作为锁,保证线程同步
- 从单例对象的高速缓存Map中获取beanName对应的单例对象【变量 singletonObject】,获取成功就直接返回singletonObject
- 如果singletonObject获取不到
- 如果当前在destorySingletons中【singletonsCurrentlyInDestruction】,就抛出BeanCreationNotAllowedException
- 如果当前日志级别时调试,就打印调试级别日志:创建单例bean的共享实例:‘beanName’
- 创建单例之前的回调【beforeSingletonCreation(beanName)】,默认实现将单例注册为当前正在创建中
- 表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象【变量 newSingleton】
- 有抑制异常记录标记,没有时为true,否则为false 【变量 recordSuppressedExceptions】
- 如果没有抑制异常记录,就对抑制的异常列表【suppressedExceptions】进行实例化(LinkedHashSet)
- 从单例工厂中获取对象【变量 singletonObject】
- newSingleton设置为true,表示生成了新的单例对象
- 捕捉非法状态异常 【变量 ex】:
- 尝试从 单例对象的高速缓存Map 中获取beanName的单例对象。如果获取失败,重新抛出ex。
- 捕捉Bean创建异常 【变量 ex】
- 如果没有抑制异常记录
- 遍历抑制的异常列表,元素为suppressedException:将抑制的异常对象添加到 bean创建异常 中,这样其实就相当于 '因XXX异常导致了Bean创建异常‘ 的说法
- 抛出ex
- finally:
- 如果没有抑制异常记录,将抑制的异常列表置为null。因为suppressedExceptions是对应单个bean的异常记录, 置为null可防止异常信息的混乱
- 创建单例后的回调,默认实现将单例标记为不在创建中 【afterSingletonCreation(beanName)】
- 如果生成了新的单例对象,将beanName和singletonObject的映射关系添加到该工厂的单例缓存中
/**
* Cache of singleton objects: bean name to bean instance.
* <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
* */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* Flag that indicates whether we're currently within destroySingletons.
* <p>指示我们当前是否在destorySingletons中的标志</p>
* */
private boolean singletonsCurrentlyInDestruction = false;
/**
* List of suppressed Exceptions, available for associating related causes.
* <p>抑制的异常列表,可用于关联相关原因</p>
* */
@Nullable
private Set<Exception> suppressedExceptions;
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* <p>返回以给定名称注册的(原始)单例对象,如果尚未注册,则创建并注册一个
* 对象</p>
* @param beanName the name of the bean -- bean名
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary -- 必要时惰性地创建单例的ObjectFactory
* @return the registered singleton object -- 注册的单例对象
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
//如果beanName为null,抛出异常
Assert.notNull(beanName, "Bean name must not be null");
//使用单例对象的高速缓存Map作为锁,保证线程同步
synchronized (this.singletonObjects) {
//从单例对象的高速缓存Map中获取beanName对应的单例对象
Object singletonObject = this.singletonObjects.get(beanName);
//如果单例对象获取不到
if (singletonObject == null) {
//如果当前在destorySingletons中
if (this.singletonsCurrentlyInDestruction) {
//抛出不允许创建Bean异常:在工厂的单例销毁时不允许创建单例bean(请勿在destory方法中向BeanFactory请求Bean)
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!)");
}
//如果当前日志级别时调试
if (logger.isDebugEnabled()) {
//打印调试级别日志:创建单例bean的共享实例
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//创建单例之前的回调,默认实现将单例注册为当前正在创建中
beforeSingletonCreation(beanName);
//表示生成了新的单例对象的标记,默认为false,表示没有生成新的单例对象
boolean newSingleton = false;
//有抑制异常记录标记,没有时为true,否则为false
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
//如果没有抑制异常记录
if (recordSuppressedExceptions) {
//对抑制的异常列表进行实例化(LinkedHashSet)
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//从单例工厂中获取对象
singletonObject = singletonFactory.getObject();
//生成了新的单例对象的标记为true,表示生成了新的单例对象
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.
// 同时,单例对象是否隐式出现 -> 如果是,请继续操作,因为异常表明该状态
//因为singletonFactory.getObject()的目的就是为将beanName的
// 单例对象注册到单例对象的高速缓存Map中,忽略掉注册后抛出的非法状态异常,可以保证
// beanFactory不会因为该bean注册后的后续处理而导致beanFactoury的生命周期结束
// 默认情况下,sinagletoObjects是拿不到该beanName的,但Spring的作者考虑到自定义BeanFactory的
// 情况,但不建议在singleFactory#getObject()的方法中就注册到singletonObjects中,因为spring
// 后面已经帮你将singleObject注册到singleObjects了。
// 尝试从 单例对象的高速缓存Map 中获取beanName的单例对象
singletonObject = this.singletonObjects.get(beanName);
//如果获取失败,抛出异常。
if (singletonObject == null) {
throw ex;
}
}
//捕捉Bean创建异常
catch (BeanCreationException ex) {
//如果没有抑制异常记录
if (recordSuppressedExceptions) {
//遍历抑制的异常列表
for (Exception suppressedException : this.suppressedExceptions) {
//将抑制的异常对象添加到 bean创建异常 中,这样做的,就是相当于 '因XXX异常导致了Bean创建异常‘ 的说法
ex.addRelatedCause(suppressedException);
}
}
//抛出异常
throw ex;
}
finally {
//如果没有抑制异常记录
if (recordSuppressedExceptions) {
//将抑制的异常列表置为null,因为suppressedExceptions是对应单个bean的异常记录,置为null
// 可防止异常信息的混乱
this.suppressedExceptions = null;
}
//创建单例后的回调,默认实现将单例标记为不在创建中
afterSingletonCreation(beanName);
}
//生成了新的单例对象
if (newSingleton) {
//将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
addSingleton(beanName, singletonObject);
}
}
//返回该单例对象
return singletonObject;
}
}
beforeSingletonCreation(beanName)
创建单例之前的回调:
如果 当前在创建检查中的排除bean名列表【inCreationCheckExclusions】中不包含该beanName 且 将beanName添加到 当前正在创建的bean名称列表【singletonsCurrentlyInCreation】后,出现beanName已经在当前正在创建的bean名称列表中添加过
/**
* Names of beans currently excluded from in creation checks.
* <p>当前在创建检查中排除的bean名</p>
* <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
* 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
* */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Names of beans that are currently in creation.
* <p>当前正在创建的bean名称</p>
* <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
* 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
* */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback before singleton creation.
* <p>创建单例之前的回调</p>
* <p>The default implementation register the singleton as currently in creation.
* <p>默认实现将单例注册为当前正在创建中</p>
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
//如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName添加到 当前正在创建的bean名称列表后,出现
// beanName已经在当前正在创建的bean名称列表中添加过
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
//抛出 当前正在创建的Bean异常
throw new BeanCurrentlyInCreationException(beanName);
}
}
afterSingletonCreation(beanName);
创建单例后的回调:
如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName从 当前正在创建的bean名称列表 异常后,出现 beanName已经没在当前正在创建的bean名称列表中出现过
/**
* Names of beans currently excluded from in creation checks.
* <p>当前在创建检查中排除的bean名</p>
* <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
* 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
* */
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Names of beans that are currently in creation.
* <p>当前正在创建的bean名称</p>
* <p>Collections.newSetFromMap(Map):Collections提供了一种保证元素唯一性的Map实现,
* 就是用一个Set来表示Map,它持有这个Map的引用,并且保持Map的顺序、并发和性能特征。</p>
* */
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* Callback after singleton creation.
* <p>创建单例后的回调</p>
* <p>The default implementation marks the singleton as not in creation anymore.
* <p>默认实现将单例标记为不在创建中</p>
* @param beanName the name of the singleton that has been created -- 已创建的单例的名称
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
//如果 当前在创建检查中的排除bean名列表中不包含该beanName 且 将beanName从 当前正在创建的bean名称列表 异常后,出现
// beanName已经没在当前正在创建的bean名称列表中出现过
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
//抛出非法状态异常:单例'beanName'不是当前正在创建的
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
addSingleton(beanName, singletonObject)
将beanName和singletonObject的映射关系添加到该工厂的单例缓存中:
- 将映射关系添加到singletonObjects【单例对象的高速缓存】中
- 移除beanName在singletonFactories【单例工厂缓存】中的数据
- 移除beanName在earlySingletonObjects【早期单例对象的高速缓存】的数据
- 将beanName添加到registeredSingletons【已注册的单例集】中
/**
* Cache of singleton objects: bean name to bean instance.
* <p>单例对象的高速缓存:beam名称-bean实例,所有bean对象最终都会放到对象中</p>
* */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* Cache of singleton factories: bean name to ObjectFactory.
* <p>单例工厂的缓存:bean名称 - ObjectFactory </p>
* */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/**
* Cache of early singleton objects: bean name to bean instance.
* <p>早期单例对象的高速缓存:bean名称 - bean实例</p>
* <p>当从singletonFactories中获取到对应对象后,就会放到这个缓存中</p>
* */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/**
* Set of registered singletons, containing the bean names in registration order.
* <p>已注册的单例集,按照注册顺序包含bean名称</p>
* <p>用于保证工厂内的beanName是唯一的</p>
* */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>将给定的单例对象添加到该工厂的单例缓存中。</p>
* <p>To be called for eager registration of singletons.
* <p>被称为渴望注册的单例</p>
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
//将映射关系添加到单例对象的高速缓存中
this.singletonObjects.put(beanName, singletonObject);
//移除beanName在单例工厂缓存中的数据
this.singletonFactories.remove(beanName);
//移除beanName在早期单例对象的高速缓存的数据
this.earlySingletonObjects.remove(beanName);
//将beanName添加到已注册的单例集中
this.registeredSingletons.add(beanName);
}
}