1. 准备

在上一个阶段的基础之上进行下一步分析

开始的地方

//这里是处理BeanDefinition的地方,具体委托给BeanDefinitionParserDelegate完成,ele对应XML元素,DOM树元素

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

    //BeanDefinitionHolder是BeanDefiniton对象的封装类,封装类BeanDefinition,Bean的名字和别名,用它完成向Ioc容器注册

    //得到这个BeanDefinitionHolder就说明BeanDefinition是通过BeanDefinitionParserDelegate对XML元素按SpringBean的规则解析得到

    //这里只关注解析,方法进入这里

    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

    if (bdHolder != null) {

        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

  

        try {

            //在上一个阶段,已经解析好了BeanDefinition,然后在这里向IoC容器注册BeanDefinition

            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());

        catch (BeanDefinitionStoreException var5) {

            this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);

        }

        //在BeanDefinition向IoC容器注册完以后,发送消息

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

    }

  

}

 

2. 开始分析

BeanDefinitionReaderUtil.registerBeanDefinition

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {

    String beanName = definitionHolder.getBeanName();

    //注册BeanDefinition

    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 aliase = var4[var6];

            registry.registerAlias(beanName, aliase);

        }

    }

}

DefaultListableBeanFactory. 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 {

            ((AbstractBeanDefinition)beanDefinition).validate();

        catch (BeanDefinitionValidationException var7) {

            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var7);

        }

    }

 

    Map var3 = this.beanDefinitionMap;

    //注册的过程需要synchronized,保证数据的一致性

    synchronized(this.beanDefinitionMap) {

        //这里检查是不是有相同名字的BeanDefinition已经在IoC容器中注册了,如果有相同的名字BeanDefinition,但是又不允许覆盖,那么会抛出异常

        BeanDefinition oldBeanDefinition = (BeanDefinition)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.");

            }

 

            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 (this.logger.isInfoEnabled()) {

                this.logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");

            }

        else {

            //这是正常注册BeanDefinition的过程,把Bean的名字存入到beanDefinitionNames的同时,把beanName作为Map的Key,把beanDefinition作为value存入到IoC容器持有的

            //beanDefinitionMap中

            this.beanDefinitionNames.add(beanName);

            this.frozenBeanDefinitionNames = null;

        }

        //这里是个Map<String,BeanDefinition>,在DefaultListableBeanFactory中,由此也能看出IoC容器中持有一个Map

        this.beanDefinitionMap.put(beanName, beanDefinition);

    }

 

    this.resetBeanDefinition(beanName);

}

 

3. 流程图分析

 

4. 总结

这个阶段比较容易,不过是把解析好的BeanDefinition放如IoC容器中的Map当中即可