`
diecui1202
  • 浏览: 97179 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring 4-注册的具体过程

阅读更多

二、注册的具体过程

1、职责类
  1. 由DefaultListableBeanFactory来完成,该接口实现了ListableBeanFactory和BeanDefinitionRegistry接口;
2、源码解读

前一节中谈到,生成BeanDefinition后,由 BeanDefinitionReaderUtils.registerBeanDefinition()来完成向容器中注册Bean定义信息,该方法即 调用了下面的registerBeanDefinition()方法;下面是DefaultListableBeanFactory实现 BeanDefinitionRegistry接口的部分:

//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "'beanName' must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");
    // 普通的bean,在生成BeanDefinition时,都是GenericBeanDefinition的实例,它是AbstractBeanDefinition的子类
    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) {
        // 先看一下存放BeanDefinition的map里是否已经包含了相同beanName的BeanDefinition
        Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        if (oldBeanDefinition != null) {
            // 如果已经存在,则需要根据容器的属性(beanDefinition是否可以被覆盖,默认为true)来做不同的处理
            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 {
            // 如果map中没有该beanName,则将beanNames存放在list中
            this.beanDefinitionNames.add(beanName);
            this.frozenBeanDefinitionNames = null;
        }
        // 将beanName及beanDefinition放在map中,完成注册
        this.beanDefinitionMap.put(beanName, beanDefinition);

        resetBeanDefinition(beanName);
    }
}

public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
    Assert.hasText(beanName, "'beanName' must not be empty");

    synchronized (this.beanDefinitionMap) {
        // 从map中清除指定beanName的beanDefinition
        BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.remove(beanName);
        if (bd == null) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No bean named '" + beanName + "' found in " + this);
            }
            throw new NoSuchBeanDefinitionException(beanName);
        }
        this.beanDefinitionNames.remove(beanName);
        this.frozenBeanDefinitionNames = null;

        resetBeanDefinition(beanName);
    }
}
 
3、小结
  1. 到现在为止,只是将XML里定义的bean定义信息生成GenericBeanDefinition实例,然后注册到容器中(所谓注册,也就是存放在一个map中,key为beanName,value为BeanDefinition实例);
  2. 其实,后面还有很多工作要做。。。。。。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics