Spring中调用一个BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())方法把bean的definition描述注册。
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
// 获取 beanName
String beanName = definitionHolder.getBeanName();
// 注册bean definition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
// 注册别名列表
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
下面我们看核心registerBeanDefinition的逻辑
第一部分definition的验证
// 第一部分 Bean Definition 的验证
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// bean定义验证
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
第二部分 Bean Name 在容器中的不同情况处理。
- 情况一: Bean Name 已经在容器中存在,并且拥有对应的 Bean Definition 对象。
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// bean name 是否允许重复注册,判断是否允许覆盖 Bean Definition
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
// map 中存储的 beanDefinition 是否和参数相同
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 设置 beanName 和 beanDefinition 关系
this.beanDefinitionMap.put(beanName, beanDefinition);
}
- 情况二:Bean Name 在容器中搜索 Bean Definition 失败。
else {
// 检查 bean 是否已经开始创建
// return !this.alreadyCreated.isEmpty();
// 在 Spring 中有一个叫做 markBeanAsCreated 的方法,这个方法就是用来标记 Bean 正在被创建。
// 在 Get Bean 的时候alreadyCreated会被赋值,在 Create Bean 的时候会被赋值。
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 设置 beanName 和 beanDefinition 关系
this.beanDefinitionMap.put(beanName, beanDefinition);
// bean definition 的名称列表
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
// 加入内存数据
updatedDefinitions.addAll(this.beanDefinitionNames);
// 加入当前的 beanName
updatedDefinitions.add(beanName);
// 对象替换
this.beanDefinitionNames = updatedDefinitions;
// 移除当前手工注册的beanName
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
// 设置容器数据
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
// 移除当前手工注册的beanName
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
第三部分 根据 Bean Name 进行 Bean Definition 的刷新操作。
if (existingDefinition != null || containsSingleton(beanName)) {
// 第一个条件:通过 Bean Name 搜索 Bean Definition 搜索成功
// 第二个条件:单例对象容器中包含当前 Bean Name 的实例对象
// 刷新bean definition
resetBeanDefinition(beanName);
}
在整个 resetBeanDefinition 方法中分为下面几个步骤
- 将合并的 Bean Definition (
mergedBeanDefinitions) 中可能存在 Bean Definition 中的stale属性设置为true - 摧毁当前 Bean Name 对应的单例实例
MergedBeanDefinitionPostProcessor的后置方法执行- 处理 Bean Definition 名称列表中名称和当前 Bean Name 相同的数据
protected void resetBeanDefinition(String beanName) {
// Remove the merged bean definition for the given bean, if already created.
// mergedBeanDefinition 的本质还是 Bean Definition ,在这里主要以 RootBeanDefinition 类型出现
// 合并的是 父 Bean Definition 对象和 当前的 Bean Definition
// 一个BeanDefinition是可以设置父类BeanDefinition的, 仅仅需要调用其setParentName即可, 之所以出现父子
// bean是因为Spring允许将相同bean的定义给抽出来, 成为一个父BeanDefinition, 这样其它的BeanDefinition
// 就能共用这些公共的数据了, 并且提出了RootBeanDefinition和ChildBeanDefinition之间的关系, 以及他们
// 的缺点, 从而Spring在之后的版本中引入了GenericBeanDefinition, 在Spring的生命周期中, 如果要实例化
// 一个bean则需要先将bean进行合并, 这样拿到的BeanDefinition才是信息完整的
clearMergedBeanDefinition(beanName);
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
// be necessary, rather just meant for overriding a context's default beans
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
// 从单例容器中将当前 Bean Name 从容器中剔除。
destroySingleton(beanName);
// Notify all post-processors that the specified bean definition has been reset.
// 其实 MergedBeanDefinitionPostProcessor 是 BeanPostProcessor 的子接口,
// 后置处理器执行 resetBeanDefinition 方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
if (processor instanceof MergedBeanDefinitionPostProcessor) {
// 执行后置方法的 resetBeanDefinition
((MergedBeanDefinitionPostProcessor) processor).resetBeanDefinition(beanName);
}
}
// Reset all bean definitions that have the given bean as parent (recursively).
// 递归处理,处理的目标是在 Bean Definition 的名称列表中和当前正在处理的 Bean Name 相同
for (String bdName : this.beanDefinitionNames) {
if (!beanName.equals(bdName)) {
BeanDefinition bd = this.beanDefinitionMap.get(bdName);
// Ensure bd is non-null due to potential concurrent modification of beanDefinitionMap.
// beanName 等于 父名称,说明没有父类了,如果不等于,说明还有,那么就递归调用
if (bd != null && beanName.equals(bd.getParentName())) {
// 递归刷新 beanName 对应的 beanDefinition
resetBeanDefinition(bdName);
}
}
}
}
本文详细讲解了Spring中BeanDefinition注册过程,包括BeanDefinition验证、注册策略和BeanDefinition刷新,重点展示了如何处理BeanName冲突及BeanDefinition更新操作。
1017

被折叠的 条评论
为什么被折叠?



