Spring源码解读3——Bean资源的注册

上一节中注册的入口:

public class DefaultBeanDefinitionDocumentReader{

	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
                //对于既不是<Import>元素,又不是<Alias>元素的元素,即Spring配置文件中普通的<Bean>元素
                //的解析由BeanDefinitionParserDelegate类的parseBeanDefinitionElement方法来实现。
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				//向Spring IoC容器注册解析得到的Bean定义,这是Bean定义向IoC容器注册的入口
                                //registry就是new Reader时传入的factory
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
		}
	}
}

实现:

public class BeanDefinitionReaderUtils{

	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {
		String beanName = definitionHolder.getBeanName();
                //向IoC容器注册BeanDefinition 
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
		//如果解析的BeanDefinition有别名,向容器为其注册别名 
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String aliase : aliases) {
				registry.registerAlias(beanName, aliase);
			}
		}
	}
}

DefaultListableBeanFactory中使用一个HashMap的集合对象存放IoC容器中注册解析的BeanDefinition

public class DefaultListableBeanFactory{

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

	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) {
			Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
                        //检查是否有同名的BeanDefinition已经在IoC容器中注册,如果已经注册,  
                        //并且不允许覆盖已注册的Bean,则抛出注册失败异常  
			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 {//如果允许覆盖,则同名的Bean,后注册的覆盖先注册的  
					if (this.logger.isInfoEnabled()) {
						this.logger.info("Overriding bean definition for bean '" + beanName +
								"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
					}
				}
			}
                        //IoC容器中没有已经注册同名的Bean,按正常注册流程注册  
			else {
				this.beanDefinitionNames.add(beanName);
				this.frozenBeanDefinitionNames = null;
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
                        //重置所有已经注册过的BeanDefinition的缓存  
			resetBeanDefinition(beanName);
		}
	}
}

编程式调用:

ClassPathResource res = new ClassPathResource("applicationContext.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
BeanDefinition bd =factory.getBeanDefinition("userBean");
PropertyValue pv =bd.getPropertyValues().getPropertyValue("id");
TypedStringValue valueHolder = (TypedStringValue) pv.getValue();
System.out.println(valueHolder.getValue());

 

转载于:https://my.oschina.net/u/2286010/blog/704890

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值