zoukankan      html  css  js  c++  java
  • 在IoC容器中的注册

    概念

    载入和解析Bean定义信息而得到BeanDefinition后,还需要将IoC容器注册这些BeanDefinition,才能让IoC容器使用。这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的。通过分析,我们可以看到,在IoC容器内部将BeanDefinition注入到BeanFactory的一个HashMap中去,IoC容器就是通过这个HashMap来持有BeanDefinition数据的。


    分析注册过程

    • 解析完<bean>后,将解析结果封装在BeanDefinitionHolder中,然后将其向容器进行注册。代码如下:

    //DefaultBeanDefinitionDocumentReader的processBeanDefinition方法
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    		//对bean元素开始解析
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    		if (bdHolder != null) {
    			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    			try {
    				// Register the final decorated instance.
            //开始注册过程
    				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    			}
    			catch (BeanDefinitionStoreException ex) {
    				getReaderContext().error("Failed to register bean definition with name '" +
    						bdHolder.getBeanName() + "'", ele, ex);
    			}
    			// Send registration event.
    			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    		}
    	}
    

    //BeanDefinitionReaderUtils的registerBeanDefinition方法,这个BeanDefinitionRegistry是个接口
    //DefaultListableBeanFactory实现了这个接口,在这里也就是之前创建的DefaultListableBeanFactory
    public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    	// Register bean definition under primary name.
    	String beanName = definitionHolder.getBeanName();
    //开始实际注册过程
    	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
    	// Register aliases for bean name, if any.
    	String[] aliases = definitionHolder.getAliases();
    	if (aliases != null) {
    		for (String aliase : aliases) {
    			registry.registerAlias(beanName, aliase);
    		}
    	}
    }
    

    //DefaultListableBeanFactory中的注册方法registerBeanDefinition
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    	Assert.hasText(beanName, &quot;Bean name must not be empty&quot;);
    	Assert.notNull(beanDefinition, &quot;BeanDefinition must not be null&quot;);
    
    	if (beanDefinition instanceof AbstractBeanDefinition) {
    		try {
    			((AbstractBeanDefinition) beanDefinition).validate();
    		}
    		catch (BeanDefinitionValidationException ex) {
    			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    					&quot;Validation of bean definition failed&quot;, ex);
    		}
    	}
    //注册过程需要synchronized,保持数据一致性
    	synchronized (this.beanDefinitionMap) {
      //这里检查是不是有相同名字的BeanDefinition已经在IoC容器中注册了,如果有相同名宇的
      //BeanDefinition,但又不允许搜盖,那么会抛出异常
    		Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
    		if (oldBeanDefinition != null) {
    			if (!this.allowBeanDefinitionOverriding) {
    				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
    						&quot;Cannot register bean definition [&quot; + beanDefinition + &quot;] for bean '&quot; + beanName +
    						&quot;': There is already [&quot; + oldBeanDefinition + &quot;] bound.&quot;);
    			}
    			else {
    				if (this.logger.isInfoEnabled()) {
    					this.logger.info(&quot;Overriding bean definition for bean '&quot; + beanName +
    							&quot;': replacing [&quot; + oldBeanDefinition + &quot;] with [&quot; + beanDefinition + &quot;]&quot;);
    				}
    			}
    		}
      //这是正常注册BeanDefinition的过程,把Bean的名字存入到beanDefinitionNames的同时.把
      //beanName作为Map的key,把beanDefinition作为value存入到IoC容器持有的beanDefinitionMap中去
    		else {
    			this.beanDefinitionNames.add(beanName);
    			this.frozenBeanDefinitionNames = null;
    		}
    		this.beanDefinitionMap.put(beanName, beanDefinition);
    	}
    
    	resetBeanDefinition(beanName);
    }</code></pre>
    


    • 完成了BeanDefinition的注册,就完成了IoC容器的初始化过程。此时,在使用的IoC容器DefaultListableBean-Factory中已经建立了整个Bean的配置信息,而且这些BeanDefinition已经可以被容器使用了,它们都在beanD-efinitionMap里被检索和使用。容器的作用就是对这些信息进行处理和维护。这些信息是容器建立依赖反转的基础。
  • 相关阅读:
    Codeforces 631D Messenger KMP
    Google Codejam 2016 Round1A Problem C BFFs 简单图论
    ACM常用数论知识 总结
    C++ 虚函数表
    HDU 5661 Claris and XOR 贪心
    2013亚洲区域赛长沙站 ZOJ 3732 Graph Reconstruction
    [C++] upper_bound和lower_bound
    2015合肥网络赛 HDU 5489 Removed Interval LIS+线段树(树状数组)
    hdu 3532 Max Angle(atan2的使用)
    poj 1106 Transmitters (计算几何,叉积||极角排序)
  • 原文地址:https://www.cnblogs.com/huangzefeng/p/10322416.html
Copyright © 2011-2022 走看看