Spring 5 AbstractBeanFactory – getBean() 源码分析(一)
Spring 5 AbstractBeanFactory – getBean() 源码分析(二)
相关源码注释
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 源码注释
相关源码注释
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 源码注释
containsBeanDefinition(beanName)
该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
该方法在 AbstractBeanFactory 中是抽象方法
/**
* Check if this bean factory contains a bean definition with the given name.
* Does not consider any hierarchy this factory may participate in.
* Invoked by {@code containsBean} when no cached singleton instance is found.
* <p>该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
* 未找到缓存的单例实例时,由{@code containsBena}调用。</p>
* <p>Depending on the nature of the concrete bean factory implementation,
* this operation might be expensive (for example, because of directory lookups
* in external registries). However, for listable bean factories, this usually
* just amounts to a local hash lookup: The operation is therefore part of the
* public interface there. The same implementation can serve for both this
* template method and the public interface method in that case.
* <p>根据具体bean工厂实现的性质,此操作可能很昂贵(例如,由于在外部注册表中进行目录
* 寻找)。但是,对应可列出的bean工厂,这通常只相当于本地哈希查找:因此,该操作是该处
* 工厂接口的一部分。在这种情况下,该模板方法和公共接口方法都可以使用相同的实现。</p>
* @param beanName the name of the bean to look for - 要查找的bean名
* @return if this bean factory contains a bean definition with the given name
* - 如果此bean工厂包含具有给定名称的bean定义。
* @see #containsBean
* @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
*/
protected abstract boolean containsBeanDefinition(String beanName);
由 DefaultListableBeanFactory 实现:
/**
* Map of bean definition objects, keyed by bean name.
* <p>Bean定义对象的映射,以Bean名称为键</p>
* */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/**
* 本地工厂中BeanDefinition对象映射【beanDefinitionMap】中是否存在beanName该键名
* @param beanName the name of the bean to look for -- 要寻找的bean名
*/
@Override
public boolean containsBeanDefinition(String beanName) {
//如果beanName为null,抛出异常
Assert.notNull(beanName, "Bean name must not be null");
//从Beand定义对象映射中判断beanName是否存在该键
return this.beanDefinitionMap.containsKey(beanName);
}
originalBeanName(name)
获取name对应的规范名称【全类名/最终别名】,如果name前面有’&’,则会返回’&’+规范名称【全类名】
/**
* <p>获取name对应的规范名称【全类名/最终别名】,如果name前面有'&',则会返回'&'+规范名称【全类名】</p>
* Determine the original bean name, resolving locally defined aliases to canonical names.
* <p>确定原始bean名,将本地定义的别名解析为规范名称</p>
* @param name the user-specified name - 用户指定的名称
* @return the original bean name 原始bena名
*/
protected String originalBeanName(String name) {
//获取name对应的规范名称【全类名】,包括以'&'开头的name
String beanName = transformedBeanName(name);
//如果name的开头有'&'
if (name.startsWith(FACTORY_BEAN_PREFIX)) {
//对beanName拼接上'&'在开头位置
beanName = FACTORY_BEAN_PREFIX + beanName;
}
//返回规范的beanName
return beanName;
}
transformedBeanName(name);
去除name开头的’&‘字符,获取name最终的规范名称【最终别名或者是全类名】:去除开头的’&'字符,返回剩余的字符串得到转换后的Bean名称, 然后通过递归形式在 aliasMap【别名映射到规范名称集合】中得到最终的规范名称
/**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
* <p>返回Bean名称,如果必要,去除工厂取消前缀,并将别名解析为规范名称</p>
* @param name the user-specified name - 用户指定的名称
* @return the transformed bean name - 转换后的bena名称
*/
protected String transformedBeanName(String name) {
//去除开头的'&'字符,返回剩余的字符串得到转换后的Bean名称,然后通过递归形式在
// aliasMap【别名映射到规范名称集合】中得到最终的规范名称
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
BeanFactoryUtils.transformedBeanName(name)
去除开头的’&'字符,返回剩余的字符串作为转换后的Bean名称【可能是全类名】:
- 如果name为null,抛出异常
- 如果name不是以’&'开头,就直接返回
- 从具有FactoryBean前缀的名称缓存到剥离的名称的ConcurrentHashMap【transformedBenaNameCache】 中获取bean名对应的转换后的名称并返回
- 获取不到时就构建一个:从name的开头位置去掉’&’,再重新检查是否还是以’&‘开头,是的话就再截直到没有出现’&'开头为止。所得到 的字符串就是Bean名称【可能是全类名】
/**
* Return the actual bean name, stripping out the factory dereference
* prefix (if any, also stripping repeated factory prefixes if found).
* <p>返回实际的bean名称,删除工厂取消引用前缀(如果有的话,还删除重复的
* 工厂前缀(如果找到))</p>
* <p>用于获取以'&'开头的name对应的bean名,如果bean不是'&'开头,就直接返回该name</p>
* @param name the name of the bean - bean名
* @return the transformed name - 转换后的名称
* @see BeanFactory#FACTORY_BEAN_PREFIX
*/
public static String transformedBeanName(String name) {
//如果bean名为null,抛出异常
Assert.notNull(name, "'name' must not be null");
//如果bean名不是以'&'开头,就直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
//从transformedBenaNameCache中获取bean名对应的转换后的名称
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
//从beanName的开头位置去掉'&',并重新赋值给beanName,再重新检查是还是以'&'开头,是的话就再截
// 知道开头不是以'&'开头后,加入到transformedBeanNameCache中
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
markBeanAsCreated(beanName)
为指定的Bean标记为已经创建(或将要创建)
/**
* Names of beans that have already been created at least once.
* <p>至少已经创建一次的bean名称</p>
* */
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
/**
* Map from bean name to merged RootBeanDefinition.
* <p>从bean名称映射到合并的RootBeanDefinition</p>
* */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/**
* Mark the specified bean as already created (or about to be created).
* 为指定的Bean标记为已经创建(或将要创建)
* <p>This allows the bean factory to optimize its caching for repeated
* creation of the specified bean.
* <p>这允许bean工厂优化其缓存,以便重复创建指定bean</p>
* @param beanName the name of the bean - bean名
*/
protected void markBeanAsCreated(String beanName) {
//如果beanName还没有创建
if (!this.alreadyCreated.contains(beanName)) {
//同步,使用mergedBenDefinitions作为锁
synchronized (this.mergedBeanDefinitions) {
//如果beanName还没有创建
if (!this.alreadyCreated.contains(beanName)) {
// Let the bean definition get re-merged now that we're actually creating
// the bean... just in case some of its metadata changed in the meantime.
// 在我们实际创建时,重新合并bean定义。。以防万一期间的某些元数据发生了变化
// 删除beanName合并bean定义,在下次访问时重新创建
clearMergedBeanDefinition(beanName);
this.alreadyCreated.add(beanName);
}
}
}
}
clearMergedBeanDefinition(beanName);
将beanName对应的合并后RootBeanDefinition对象标记为重新合并定义
/**
* <p>将beanName对应的合并后RootBeanDefinition对象标记为重新合并定义</p>
* Remove the merged bean definition for the specified bean,
* recreating it on next access.
* <p>删除指定的bean的合并bean定义,在下次访问时重新创建</p>
* <p>获取beanName合并后RootBeanDefinition对象【变量 bd】,将bd标记为需要重新合并定义【RootBeanDefinition#stale】/p>
* @param beanName the bean name to clear the merged definition for
* - bean名称以清除其合并定义
*/
protected void clearMergedBeanDefinition(String beanName) {
//从合并后BeanDefinition集合缓存中获取beanName对应的合并后RootBeanDefinition对象
RootBeanDefinition bd = this.mergedBeanDefinitions.get(beanName);
//如果成功获取到了bd
if (bd != null) {
//将bd标记为需要重新合并定义
bd.stale = true;
}
}
getMergedLocalBeanDefinition(beanName)
获取beanName合并后的本地RootBeanDefintiond
Spring 5 AbstractBeanFactory – getMergedLocalBeanDefinition 源码解析
checkMergedBeanDefinition(mbd, beanName, args);
检查给定的合并后mbd,不合格会引发验证异常:
- 如果mbd所配置的bean是抽象的就抛出异常
/**
* Check the given merged bean definition,
* potentially throwing validation exceptions.
* <p>检查给定的合并后mbd,不合格会引发验证异常
</p>
* @param mbd the merged bean definition to check -- 要检查的合并后RootBeanDefinition
* @param beanName the name of the bean -- bean名
* @param args the arguments for bean creation, if any -- 创建bean的参数(如果有)
* @throws BeanDefinitionStoreException in case of validation failure -- 如果验证失败
*/
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
throws BeanDefinitionStoreException {
//如果mbd所配置的bean是抽象的
if (mbd.isAbstract()) {
//抛出Bean为抽象异常
throw new BeanIsAbstractException(beanName);
}
}
isDependent(beanName, dep)
判断beanName是否已注册依赖于dependentBeanName的关系
由 DefaultSingletonBeanRegistry 实现
/**
* <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
* Map between dependent bean names: bean name to Set of dependent bean names.
* <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
* */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/**
* Determine whether the specified dependent bean has been registered as
* dependent on the given bean or on any of its transitive dependencies.
* <p>确定指定的依赖bean是否已注册为依赖于给定bean或其任何传递依赖</p>
* @see #isDependent(String, String, Set)
* @param beanName the name of the bean to check -- 要检查的bean名
* @param dependentBeanName the name of the dependent bean -- 依赖名称
* @since 4.0
*/
protected boolean isDependent(String beanName, String dependentBeanName) {
//使用依赖bean关系Map作为锁,保证线程安全
synchronized (this.dependentBeanMap) {
return isDependent(beanName, dependentBeanName, null);
}
}
registerDependentBean(dep, beanName)
注册beanName与dependentBeanNamed的依赖关系:
- 获取name的最终别名或者是全类名 【变量 canonicalName】
- 注册到存储 bean名到该bean名所要依赖的bean名 的Map【dependentBeanMap】:
- 使用dependentBeanMap作为锁,保证线程安全
- 获取canonicalName对应的用于存储依赖Bean名的Set集合,如果没有就创建一个LinkeHashSet,并与canonicalName绑定到dependentBeans中
- 如果dependendBeans已经添加过来了dependentBeanName,就结束该方法,不执行后面操作。
- 注册到 存储 bean名到依赖于该bean名的bean名 的Map【dependenciesForBeanMap】:
- 使用Bean依赖关系Map作为锁,保证线程安全
- 添加dependendtBeanName依赖于cannoicalName的映射关系到dependenciesForBeanMap中
/**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* <p>为给定的bean注册一个从属bean,要在给定的bean被销毁之前将其销毁。</p>
* @param beanName the name of the bean -- bean名
* @param dependentBeanName the name of the dependent bean -- 依赖bean名
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
//获取name的最终别名或者是全类名
String canonicalName = canonicalName(beanName);
//使用 存储 bean名到该bean名所要依赖的bean名 的Map 作为锁,保证线程安全
synchronized (this.dependentBeanMap) {
//获取canonicalName对应的用于存储依赖Bean名的Set集合,如果没有就创建一个LinkeHashSet,并与canonicalName绑定到dependentBeans中
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
//如果dependendBeans已经添加过来了dependentBeanName,就结束该方法,不执行后面操作。
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
//使用Bean依赖关系Map作为锁,保证线程安全
synchronized (this.dependenciesForBeanMap) {
//添加dependendtBeanName依赖于cannoicalName的映射关系到 存储 bean名到依赖于该bean名的bean名 的Map中
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
canonicalName(beanName)
获取name的最终别名或者是全类名
1. 通过递归形式在aliasMap【别名映射到规范名称集合】中得到最终的规范名称
由 SimpleAliasRegistry 实现
/**
* Map from alias to canonical name.
* <p>从别名映射到规范名称</p>
* <p>整个Map数据结构应该要抽象理解为一个二维数组,因为在检索别名的时候,是可以通过别名查别名的。</p>
* <p>举个栗子:
* <ol>
* <li>A是B的别名,C是B的别名,存放到aliasMap中的数据结构就是:[{key=B,val=A},{key=C,val=B}]</li>
* <li>当要获取A的所有别名[B,C]时:先获取A的Key->B,则通过递归形式获取B的key->C。</li>
* </ol>
* </p>
* */
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
/**
* Determine the raw name, resolving aliases to canonical names.
* <p>确定原始名称,将别名解析为规范名称</p>
* @param name the user-specified name - 用户指定的名称
* @return the transformed name - 转换后的名称
*/
public String canonicalName(String name) {
//规范名称初始化化传入的name
String canonicalName = name;
// Handle aliasing... 处理别名
String resolvedName;
//从下面代码可以看出,aliasMap的存储形式是:
// C是真正的规范名称,A,B都是别名:
// aliasMap={key:A,val:B;key:B,val:C},通过A拿到B,再通过B拿到C
do {
//通过 规范名称 从 aliasMap中获取解析后的名称
resolvedName = this.aliasMap.get(canonicalName);
//如果找到了解析后的名称
if (resolvedName != null) {
//规范名称重新赋值为解析后名称
canonicalName = resolvedName;
}
}
//只要找到了解析后的名称
while (resolvedName != null);
return canonicalName;
}
getSingleton(beanName, singletonFactory)
返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:
Spring 5 DefaultSingletonBeanRegistry – getSingleton(String,ObjectFactory) 源码解析
createBean(beanName, mbd, args);
为给定的合并后BeanDefinition(和参数)创建一个bean实例
Spring 5 AbstractBeanFactory – createBean 源码解析(一)
Spring 5 AbstractBeanFactory – createBean 源码解析(二)
destroySingleton(beanName);
销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
由 DefaultSingletonBeanRegistry 实现
/**
* Disposable bean instances: bean name to disposable instance.
* <p>一次性Bean实例:bean名称 - DisposableBean实例。</p>
* */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
/**
* Destroy the given bean. Delegates to {@code destroyBean}
* if a corresponding disposable bean instance is found.
* <p>销毁给定的bean。如果找到相应的一次性Bean实例,则委托给{@code destoryBean}</p>
* @param beanName the name of the bean -- bean名
* @see #destroyBean
*/
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
// 删除给定名称的已注册的单例(如果有)
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
// 销毁相应的DisposableBean实例
// DisposableBean:要在销毁时释放资源的bean所实现的接口.包括已注册为一次性的内部bean。
// 在工厂关闭时调用。
DisposableBean disposableBean;
//同步,将 一次性Bean实例:bean名称 - DisposableBean实例 作为锁
synchronized (this.disposableBeans) {
//从disposableBeans移除出disposableBean对象
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
//销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
destroyBean(beanName, disposableBean);
}
removeSingleton(beanName);
从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败,则能够清理饿汉式注册 的单例
/**
* 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);
/**
* 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.
* <p>从该工厂单例缓存中删除具有给定名称的Bean。如果创建失败,则能够清理饿汉式注册
* 的单例</p>
* @param beanName the name of the bean -- bean名
* @see #getSingletonMutex()
*/
protected void removeSingleton(String beanName) {
//同步,使用 单例对象的高速缓存:beam名称-bean实例 作为锁
synchronized (this.singletonObjects) {
//删除 单例对象的高速缓存:beam名称-bean实例 的对应数据
this.singletonObjects.remove(beanName);
//删除 单例工厂的缓存:bean名称 - ObjectFactory 的对应数据
this.singletonFactories.remove(beanName);
//删除 单例对象的高速缓存:beam名称-bean实例 的对应数据
this.earlySingletonObjects.remove(beanName);
//删除 已注册的单例集,按照注册顺序包含bean名称 的对应数据
this.registeredSingletons.remove(beanName);
}
}
destroyBean(beanName, disposableBean);
/**
* <p>存储 bean名到该bean名所要依赖的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}</p>
* Map between dependent bean names: bean name to Set of dependent bean names.
* <p>在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称</p>
* */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/**
* <p>存储 bean名到依赖于该bean名的bean名 的Map,不理解的请看 {@link #registerDependentBean(String, String)}<</p>
* Map between depending bean names: bean name to Set of bean names for the bean's dependencies.
* <p>在相关的Bean名称之j键映射:bean名称 bean依赖项的Bean名称集</p>
* */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
/**
* Destroy the given bean. Must destroy beans that depend on the given
* bean before the bean itself. Should not throw any exceptions.
* <p>销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
* 不应抛出任何异常</p>
* @param beanName the name of the bean -- bean名
* @param bean the bean instance to destroy -- 要销毁的bean实例
*/
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
// 先触发从依赖的bean的破坏
Set<String> dependencies;
//同步,使用 在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称 作为锁
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
// 在完全同步内以确保断开连续集
//从dependentBeanMap中移除出beanName对应的依赖beanName集
dependencies = this.dependentBeanMap.remove(beanName);
}
//如果存在依赖的beanName集
if (dependencies != null) {
if (logger.isTraceEnabled()) {
logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
//遍历依赖的BeanName
for (String dependentBeanName : dependencies) {
递归删除dependentBeanName的实例
destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now... 实现上现在销毁的bean
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... 触发销毁所包含的bean
Set<String> containedBeans;
//同步,使用 在包含的Bean名称之间映射:bean名称 - Bean包含的Bean名称集 作为锁
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
//如果存在BeanName包含的bean名称集
if (containedBeans != null) {
//遍历BeanName包含的bean名称集
for (String containedBeanName : containedBeans) {
//递归删除containedBeanName的实例
destroySingleton(containedBeanName);
}
}
// Remove destroyed bean from other beans' dependencies.
// 从其他bean的依赖项中删除破坏的bean
//同步,在相关的Bean名称之间映射:bean名称 - 一组相关的Bean名称 作为锁
synchronized (this.dependentBeanMap) {
//遍历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();
//从其它bean的依赖bean集合中移除beanName
dependenciesToClean.remove(beanName);
//如果依赖bean集合没有任何元素了
if (dependenciesToClean.isEmpty()) {
//将整个映射关系都删除
it.remove();
}
}
}
// Remove destroyed bean's prepared dependency information.
// 删除销毁的bean准备的依赖的依赖项信息
// 从 在相关的Bean名称之键映射:bean名称 bean依赖项的Bean名称集 删除beanName的映射关系
this.dependenciesForBeanMap.remove(beanName);
}
destroySingleton(dependentBeanName);
销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBean
由 DefaultSingletonBeanRegistry 实现。
/**
* Disposable bean instances: bean name to disposable instance.
* <p>一次性Bean实例:bean名称 - DisposableBean实例。</p>
* */
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
/**
* Destroy the given bean. Delegates to {@code destroyBean}
* if a corresponding disposable bean instance is found.
* <p>销毁给定的bean。如果找到相应的一次性Bean实例,则委托给{@code destoryBean}</p>
* @param beanName the name of the bean -- bean名
* @see #destroyBean
*/
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
// 删除给定名称的已注册的单例(如果有)
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
// 销毁相应的DisposableBean实例
// DisposableBean:要在销毁时释放资源的bean所实现的接口.包括已注册为一次性的内部bean。
// 在工厂关闭时调用。
DisposableBean disposableBean;
//同步,将 一次性Bean实例:bean名称 - DisposableBean实例 作为锁
synchronized (this.disposableBeans) {
//从disposableBeans移除出disposableBean对象
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
//销毁给定bean。必须先销毁依赖于给定bean的bean。然后再销毁bean。
destroyBean(beanName, disposableBean);
}
getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接 返回beanInstance实例
/**
* <p>从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接
* 返回beanInstance实例</p>
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
* <p>获取给定Bean实例对象,对于FactoryBean,可以是Bean实例本身,也可以
* 是它创建的对象</p>
* @param beanInstance the shared bean instance - 共享bean实例
* @param name name that may include factory dereference prefix - 可能包含工厂取消引用前缀的名字
* @param beanName the canonical bean name - 规范bean名
* @param mbd the merged bean definition - 合并的bean定义
* @return the object to expose for the bean - 为bean公开的对象
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
// 如果 name为FactoryBean的解引用.name是以'&'开头,就是FactoryBean的解引用
if (BeanFactoryUtils.isFactoryDereference(name)) {
//如果beanInstance是NullBean实例
if (beanInstance instanceof NullBean) {
//返回beanInstance
return beanInstance;
}
//如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
//抛出Bean不是一个Factory异常
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
//如果mbd不为null
if (mbd != null) {
//设置mbd是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
//返回beanInstance
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 现在我们有了Bean实例,他可能是一个普通的Bean或FactoryBean。
// 如果它是FactoryBean,我们使用它来创建一个Bean实例,除非调用者确实需要对工厂的引用。
//如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
//定义为bean公开的对象,初始化为null
Object object = null;
//如果mbd不为null
if (mbd != null) {
//更新mbd的是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
else {
//从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
object = getCachedObjectForFactoryBean(beanName);
}
//如果object为null
if (object == null) {
// Return bean instance from factory.
// 从工厂返回Bean实例
//将beanInstance强转为FactoryBean对象
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 如果是单例对象,则缓存从FactoryBean获得的对象、
//如果mbd为null && 该BeanFactory包含beanName的BeanDefinition对象。
if (mbd == null && containsBeanDefinition(beanName)) {
//获取beanName合并后的本地RootBeanDefintiond对象
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"【一般是指只有AOP相关的prointCut配置或者
// Advice配置才会将 synthetic设置为true】
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
//返回为bean公开的对象
return object;
}
getObjectFromFactoryBean(factory, beanName, !synthetic);
Spring 5 AbstractBeanFactory – getObjectFromFactoryBean 源码解析
beforePrototypeCreation(beanName);
创建ProtoPype对象前的准备工作,默认实现 将beanName添加到 prototypesCurrentlyInCreation 中
/**
* Names of beans that are currently in creation.
* <p>当前正在创建的bean名称</p>
* */
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
/**
* <p>创建ProtoPype对象前的准备工作,默认实现 将beanName添加到 prototypesCurrentlyInCreation 中</p>
* Callback before prototype creation.
* <p>原型创建前的回调</p>
* <p>The default implementation register the prototype as currently in creation.
* <p>默认实现将原型注册为当前创建中</p>
* @param beanName the name of the prototype about to be created
* -- 将要创建的原型的名称
* @see #isPrototypeCurrentlyInCreation
*/
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
//prototypesCurrentlyInCreation:当前正在创建的bean名称
//从 prototypesCurrentlyInCreation中获取线程安全的当前正在创建的Bean对象名
Object curVal = this.prototypesCurrentlyInCreation.get();
//如果curlVal为null
if (curVal == null) {
//将beanName设置到propertysCurrentlyInCreation中
this.prototypesCurrentlyInCreation.set(beanName);
}
//如果curlValue是Stringl类型
else if (curVal instanceof String) {
//定义一个HashSet对象存放prototypesCurrentlyInCreation原有Bean名 和 beanName
Set<String> beanNameSet = new HashSet<>(2);
//将curlVal添加beanNameSet中
beanNameSet.add((String) curVal);
//将beanName添加到beanNameSet中
beanNameSet.add(beanName);
//将beanNameSet设置到propertysCurrentlyInCreation中
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
//否则,curlValue就只会是HashSet对象
//将curlVal强转为Set对象
Set<String> beanNameSet = (Set<String>) curVal;
//将beanName添加到beanNameSet中
beanNameSet.add(beanName);
}
}
afterPrototypeCreation(beanName);
创建完prototype实例后的回调,默认是将beanName从 prototypesCurrentlyInCreation 移除
/**
* Names of beans that are currently in creation.
* <p>当前正在创建的bean名称</p>
* */
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<>("Prototype beans currently in creation");
/**
* <p>创建完prototype实例后的回调,默认是将beanName从 prototypesCurrentlyInCreation 移除</p>
* Callback after prototype creation.
* <p>原型创建后的回调</p>
* <p>The default implementation marks the prototype as not in creation anymore.
* <p>默认实现将原型标记为不在创建中</p>
* @param beanName the name of the prototype that has been created
* -- 已创建的原型的名称
* @see #isPrototypeCurrentlyInCreation
*/
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
//从prototypesCurrentlyInCreation获取当前正在创建的Bean名
Object curVal = this.prototypesCurrentlyInCreation.get();
//将curlVal是String对象
if (curVal instanceof String) {
//将curlVal从prototypesCurrentlyInCreation中移除
this.prototypesCurrentlyInCreation.remove();
}
//如果curlVal是Set对象
else if (curVal instanceof Set) {
//将curValue强转为Set对象
Set<String> beanNameSet = (Set<String>) curVal;
//将beanName从beanNameSet中移除
beanNameSet.remove(beanName);
//如果beanNameSet已经没有元素了
if (beanNameSet.isEmpty()) {
//将beanNameSet从prototypesCurrentlyInCreation中移除
this.prototypesCurrentlyInCreation.remove();
}
}
}
cleanupAfterBeanCreationFailure(beanName);
在Bean创建失败后,对缓存的元数据执行适当的清理
/**
* Map from bean name to merged RootBeanDefinition.
* <p>从bean名称映射到合并的RootBeanDefinition</p>
* */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/**
* Names of beans that have already been created at least once.
* <p>至少已经创建一次的bean名称</p>
* */
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
/**
* Perform appropriate cleanup of cached metadata after bean creation failed.
* <p>在Bean创建失败后,对缓存的元数据执行适当的清理</p>
* @param beanName the name of the bean -- bean名
*/
protected void cleanupAfterBeanCreationFailure(String beanName) {
//mergedBeanDefinitions:从bean名称映射到合并的RootBeanDefinition
//使用mergedBeanDefinitions加锁,保证线程安全
synchronized (this.mergedBeanDefinitions) {
//alreadyCreated:至少已经创建一次的bean名称
//将beanName从alreadyCreated中删除
this.alreadyCreated.remove(beanName);
}
}