Spring-IOC源码解读2.3-BeanDefinition的注册

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-IOC源码解读2.3-BeanDefinition的注册相关的知识,希望对你有一定的参考价值。

在DefaultListAbleBeanFactory中通过一个HashMap持有载入的BeanDefinition信息 ,这个HashMap的定义在DefaultListAbleBeanFactory中可以看到:

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();

将解析得到的BeanDefinition向IOC容器beanDefinitionMap 注册的过程是在载入BeanDefinition完成后进行的。DefaultListAbleBeanFactory实现了BeanDefinitionRegistry接口,这个注册过程就是把解析得到的BeanDefinition设置到HashMap中去 ,有一点需要注意的是遇到同名的BeanDefinition,进行处理的时候需要根据allowBeanDefinitionOverding的配置来完成

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 {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,"Validation of bean definition failed", ex);
            }
        }
        //注册的过程需要同步保证数据一致性
        synchronized (this.beanDefinitionMap) {
            //检查是否已经注册了同名的bean,如果存在且不允许覆盖则抛出异常
            Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
            if (oldBeanDefinition != null) {
                if (!this.allowBeanDefinitionOverriding) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean ‘" + beanName + "‘: There is already [" + oldBeanDefinition + "] bound.");
                }
                else {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Overriding bean definition for bean ‘" + beanName + "‘: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                }
            }
            else {
                //正常注册过程,把bean的名字放入BeanDefinitionName的同时,把beanName作为map的key,beanDefinition作为map的value
                this.beanDefinitionNames.add(beanName);
                this.frozenBeanDefinitionNames = null;
            }
            this.beanDefinitionMap.put(beanName, beanDefinition);

            resetBeanDefinition(beanName);
        }
    }

  

完成了BeanDefinition的注册就完成了IOC容器的初始化过程,此时已经在DefaultListableBeanFactory中建立了整个bean的配置信息,这些BeanDefinition已经可以被容器使用了,容器的作用是对这些信息进行处理和维护,这些信息是容器建立依赖反转的基础

以上是关于Spring-IOC源码解读2.3-BeanDefinition的注册的主要内容,如果未能解决你的问题,请参考以下文章

Spring-IOC源码解读1-整体设计

Spring-IOC源码解读3-依赖注入

Spring-IOC源码解读2-容器的初始化过程

Spring:源码解读Spring IOC原理

二:Spring-IOC源码

Spring-IOC学习笔记-01初识