您的位置:首页 > 编程语言 > Java开发

Spring-标签-默认标签bean-注册解析BeanDefinition

2019-06-03 12:24 423 查看

对于配置文件,解析和修饰完成之后,得到了BeanDefinition,最后就是对BeanDefinition进行注册解析,
DefaultBeanDefinitionDocumentReader.java中processBeanDefinition方法

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

try {
//进行注册和解析
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}

this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}

}

BeanDefinitionReaderUtils.java中的registerBeanDefinition方法:

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
//通过beanName进行注册和解析
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
//通过别名进行注册和解析
String[] var4 = aliases;
int var5 = aliases.length;

for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}

}

1.beanName注册BeanDefinition

DefaultListableBeanFactory.java中的registerBeanDefinition方法

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
//注册前的最后一次校验,主要是对AbstructBeanDefinition属性中的methodOverrides校验,校验该方法是否与工厂方法并存或者methodOverride对应的方法不存在
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
}
}

BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
//如果对应的beanName已经存在了且在配置中不允许覆盖,则抛出异常
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
}

if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}

this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (this.hasBeanCreationStarted()) {
//map作为全局变量,存在并发问题,需要使用synchronized锁
synchronized(this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
} else {
//注册BeanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
//记录beanName
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}

this.frozenBeanDefinitionNames = null;
}

if (oldBeanDefinition != null || this.containsSingleton(beanName)) {
//重置所有的beanName对应缓存。
this.resetBeanDefinition(beanName);
}

}

对于bean的注册处理,主要是以下的步骤:

  1. 对AbstractBeanDefinition的校验,在解析XML文件时进行的校验是对格式进行校验,此处是针对AbstractBeanDefinition中的methodOverrides属性进行校验,
  2. 对beanName已经注册的情况的处理,如果设置了 不允许bean的覆盖,就抛出异常,否则直接覆盖
  3. 加入map缓存
  4. 清除解析之前留下的对应的beanName的缓存。

2.通过别名注册BeanDefinition

在SimpleAliasRegistry类中的registerAlias进行别名注册

public void registerAlias(String name, String alias) {
Assert.hasText(name, "'name' must not be empty");
Assert.hasText(alias, "'alias' must not be empty");
synchronized(this.aliasMap) {
if (alias.equals(name)) {
//当alias与BeanName同名时,删除alias
this.aliasMap.remove(alias);
} else {
String registeredName = (String)this.aliasMap.get(alias);
if (registeredName != null) {
if (registeredName.equals(name)) {
//如果别名已经存在的话,直接返回
return;
}

if (!this.allowAliasOverriding()) {
//存在的话,且不允许覆盖,抛出异常
throw new IllegalStateException("Cannot register alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
}
}
循环检查
this.checkForAliasCircle(name, alias);
//注册
this.aliasMap.put(alias, name);
}

}
}

注册alias步骤:

  1. alias与BeanName相同时,不需要处理并删除原有的alias。
  2. alias覆盖处理。若aliasName已经使用并指向了另一个BeanName,按照用户的设置进行处理。
  3. alias循环检查。当A->B存在时,若再次出现A->C->B会抛出异常
  4. 注册alias。

通知监听器解析及注册完成

通过getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder))完成,这里只实现了扩展,当程序开发人员需要对注册BeanDefinition事件进行监听时可以通过注册监听器的方式将处理逻辑写入监听器中,在目前spring并没有对此事件做任何的逻辑处理。
源码:
RederContext.java中的fireComponentRegistered:

public void fireComponentRegistered(ComponentDefinition componentDefinition) {
this.eventListener.componentRegistered(componentDefinition);
}

EmptyReaderEventListener.java中的componentRegistered方法:

public void componentRegistered(ComponentDefinition componentDefinition) {
}

以上,完成了从Bean对象的解析和注册。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: