Spring源码解析-BeanDefinition在IOC容器中的注册(三)

来源:互联网 发布:素媛用什么软件看 编辑:程序博客网 时间:2024/06/05 23:02

在上一部分,我们看到了在对BeanDefinition解析完成之后,会向注册表中注册BeanDefinition,源码如下:

processBeanDefinition(DefaultBeanDefinitionDocumentReader)

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {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(bdHolder, getReaderContext().getRegistry()); 中,这里注册器其实就是之前一直提到的底层工厂DefaultListableBeanFactory(实现了BeanDefinitionRegistry).

 

下面我们来看一下registerBeanDefinition的源码(BeanDefinitionReaderUtils)

/** * Register the given bean definition with the given bean factory. * @param definitionHolder the bean definition including name and aliases * @param registry the bean factory to register with * @throws BeanDefinitionStoreException if registration failed */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 (int i = 0; i < aliases.length; i++) {registry.registerAlias(beanName, aliases[i]);}}}


 

我们可以看到真正的注册发生在registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());这一步。继续往里跟,我们来看一下DefaultListableBeanFactory是怎么实现的

//---------------------------------------------------------------------// 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");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);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 {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);resetBeanDefinition(beanName);}}


我们看到其实底层存储这个BeanDefinition的数据结构就是一个简单的Map

( /** Map of bean definition objects, keyed by bean name */
 private final Map beanDefinitionMap = CollectionFactory.createConcurrentMapIfPossible(16);)