(spring-第8回【IoC基础篇】)BeanDefinition在IoC容器中的注册

在spring中,所有的bean都是由BeanFactory进行管理的。下面是BeanFactory的类体系结构:

我们清楚的看到,DefaultListableBeanFactory继承了BeanFactory的优良传统,同时又实现了BeanDefinitionRegistry这个注册器,那么无疑,BeanDefinition在容器中的注册任务,非他莫属。事实上,DefaultListableBeanFactory拥有一个私有的BeanDefinitonMap属性,这个属性是个哈希Map,通过把解析好的BeanDefiniton放到哈希Map中,就完成了注册。下面是注册方法:

 1 //---------------------------------------------------------------------
 2     // Implementation of BeanDefinitionRegistry interface
 3     //---------------------------------------------------------------------
 4 
 5     public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 6             throws BeanDefinitionStoreException {
 7 
 8        。。。。。。40         
41             this.beanDefinitionMap.put(beanName, beanDefinition);
42             
43 
44             resetBeanDefinition(beanName);
45         }
46     }

第41行把beanDefinition作为value,而把beanName作为key,放到beanDefinitionMap中,就完成了注册。那么,这个beanDefinition是从哪里传过来的呢?

由于我的myeclipse环境中使用的是spring源码,而非jar包,所以我们做一个小测试,我配置一个简单的<bean>,然后做一个恶简单的spring容器的启动和<bean>的加载,那么程序一定会走到41行来执行注册。我在第41行上面加上一句:beanDefinition=null;这样的话,执行到第41行就会报错,报错信息如下:

。。。。。。
17 Caused by: java.lang.NullPointerException
18     at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:881)
19     at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:628)
20     at org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionReaderUtils.java:148)
21     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(DefaultBeanDefinitionDocumentReader.java:263)
22     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:153)
23     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:132)
24     at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93)
25     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
26     at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
27     ... 14 more

从第26行倒着往上看,就是整个beanDefinition的加载与注册过程。大概过程我们一目了然:

1.由XmlBeanDefinitionReader开始加载、注册。

2.由DefaultBeanDefinitionDocumentReader开始解析。

3.由BeanDefinitionReaderUtils过渡。

4.由DefaultListableBeanFactory注册。

我们来具体分析一下这四个类。

解读第1步:Resource在加载了XML文件后,首先是由BeanDefinitionReader来解析的。下面是BeanDefinitionReader的部分子孙图和注释:

解读第2步:那么第二步所说的DefaultBeanDefinitionDocumentReader应该就是图中提到的"BeanDefinitionDocumentReader"的某个子孙了。它负责与BeanDefinitionRegistry的实现者对话。而这个"BeanDefinitionRegistry的实现者"就是DefaultListableBeanFactory。

BeanDefinitionDocumentReader的家族图也很简单,它的家谱图说明:

解读第3步:过渡类。

解读第4步:文章一开始已经分析过了。实际上,DefaultListableBeanFactory能做的事情很多,除了注册BeanDefinition外,它可以被用作一个独立的BeanFactory,又可以被基本的BeanFactory子类来继承,打开API文档你会看到,DefaultListableBeanFactory继承和实现了一堆父类,亲爹干爹一大堆,API上描述其为:"a full-fledged bean factory"(羽翼丰满的bean factory),下面是它的亲爹和干爹们:

没错,在spring王国里,它就是富二代。

原文地址:https://www.cnblogs.com/mesopotamia/p/4985152.html