7-spring源码3.2.18解读+spring技术内幕(关于BeanDefinition的注册)

来源:互联网 发布:汤珈铖 知乎 编辑:程序博客网 时间:2024/06/05 16:22

1、导读

前面已经分析过BeanDefinitionIOC容器中载入和解析过程。在这些动作完成以后,用户定义的BeanDefinition信息已经在IOC容器内建立起了自己的数据结构以及相应的数据表示,但此时这些数据还不能够提供IOC容器直接使用,需要在ioc容器中对这些BeanDefinition数据进行注册。这个注册为ioc容器提供了更友好的使用方式,在DefaultListableBeanFactory中,是通过一个HashMap来持有载入的BeanDefinition的,这个HashMap的定义在DefaultListableBeanFactory中可以看到:

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

将得到的BeanDefinitionIOC容器中的beanDefinitionMap注册是在载入BeanDefinition完成后进行的。

 

2、流程图

 

3、具体调用过程

DefaultBeanDefinitionDocumentReader类中完成资源的在载入和解析后会接着调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,this.getReaderContext().getRegistry())方法对资源进行注册,这里传递被解析的资源BeanDefinitionHolder对象以及BeanDefinitionRegistry对象,接着在该方法中会调用BeanDefinitionRegistry类的子类DefaultListableBeanFactory中的registerBeanDefinition(String beanName, BeanDefinition beanDefinition)实现方法将解析过后的信息保存到一个线程安全的HashMap对象中。

 

3.1DefaultBeanDefinitionDocumentReader

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));
    }

}

 

3.2BeanDefinitionReaderUtils

 

 

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    String[] aliases = definitionHolder.getAliases();
    if(aliases != null) {
        String[] arr$ = aliases;
        int len$ = aliases.length;

        for(int i$ = 0; i$ < len$; ++i$) {
            String aliase = arr$[i$];
            registry.registerAlias(beanName, aliase);
        }
    }

}

 

3.3DefaultListableBeanFactory

 

 

 

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 var4 = this.beanDefinitionMap;
    BeanDefinition oldBeanDefinition;
    synchronized(this.beanDefinitionMap) {
        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(this.logger.isInfoEnabled()) {
                this.logger.info("Overriding bean definition for bean \'" + beanName + "\': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }
        } else {
            this.beanDefinitionNames.add(beanName);
            this.frozenBeanDefinitionNames = null;
        }

        this.beanDefinitionMap.put(beanName, beanDefinition);
    }

    if(oldBeanDefinition != null || this.containsSingleton(beanName)) {
        this.resetBeanDefinition(beanName);
    }

}

 

 

 

以上就是关于Spring IOC容器中资源的初始化,在完成了BeanDefinition的注册,就完成了整个IOC容器的初始化过程,在使用的IOC容器中DefaultListableBeanFactory中已经建立了整个Bean的配置信息,而且这些BeanDefinition已经可以被容器所使用了,他们都在beanDefinitionMap里被检索和使用。容器的作用就是对这些信息进行维护和处理。这些信息是依赖反转的基础,有了这些基础数据,下面就可以对IOC容器进行依赖注入了。

 

 

阅读全文
0 0
原创粉丝点击