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的注册处理,主要是以下的步骤:
- 对AbstractBeanDefinition的校验,在解析XML文件时进行的校验是对格式进行校验,此处是针对AbstractBeanDefinition中的methodOverrides属性进行校验,
- 对beanName已经注册的情况的处理,如果设置了 不允许bean的覆盖,就抛出异常,否则直接覆盖
- 加入map缓存
- 清除解析之前留下的对应的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步骤:
- alias与BeanName相同时,不需要处理并删除原有的alias。
- alias覆盖处理。若aliasName已经使用并指向了另一个BeanName,按照用户的设置进行处理。
- alias循环检查。当A->B存在时,若再次出现A->C->B会抛出异常
- 注册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对象的解析和注册。
相关文章推荐
- 死磕Spring系列之二,bean标签的解析和BeanDefinition的注册
- 死磕Spring系列之二,bean标签的解析和BeanDefinition的注册
- bean标签的解析及注册(二)解析BeanDefinition
- bean标签的解析及注册(四)注册解析的beanDefinition
- bean标签的解析及注册(三)AbstractBeanDefinition属性
- Spring源码解析-BeanDefinition在IOC容器中的注册(三)
- spring解析xml中的bean的一个关键类public class BeanDefinitionParserDelegate
- Spring源码学习--Bean注入解析结果BeanDefinition
- 一、从 BeanDefinitionParserDelegate 解析xml bean元素,查看bean的各个属性(Spring3.2.12)
- Spring中的Bean标签的所有元素和属性BeanDefinitionParserDelegate
- Spring源码分析-BeanDefinition加载、解析和注册
- Spring图解将bean标签转换BeanDefinition
- Spring BeanFactory、ApplicationContext层次结构和BeanDefinition解析过程
- spring源码(8)注册解析的BeanDefinition
- 理解spring的BeanDefinition和配置文件(原文标题:动态注册bean到spring容器)
- Spring源码之旅(3)_BeanDefinition的解析与注册
- Spring 3.2 源码解析 -- XML bean 元素到 BeanDefinition 解析过程
- (spring-第8回【IoC基础篇】)BeanDefinition在IoC容器中的注册
- Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition w
- 6-spring源码3.2.18解读+spring技术内幕(关于BeanDefinition的载入和解析)