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

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

 //---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//--------------------------------------------------------------------- public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException { 。。。。。。
this.beanDefinitionMap.put(beanName, beanDefinition); resetBeanDefinition(beanName);
}
}

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

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

。。。。。。
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:881)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:628)
at org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionReaderUtils.java:148)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(DefaultBeanDefinitionDocumentReader.java:263)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:153)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:132)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
... 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王国里,它就是富二代。

(spring-第8回【IoC基础篇】)BeanDefinition在IoC容器中的注册的更多相关文章

  1. (spring-第13回【IoC基础篇】)PropertyEditor(属性编辑器)--实例化Bean的第五大利器

    上一篇讲到JavaBeans的属性编辑器,编写自己的属性编辑器,需要继承PropertyEditorSupport,编写自己的BeanInfo,需要继承SimpleBeanInfo,然后在BeanIn ...

  2. Spring+SpringMVC+MyBatis+easyUI整合基础篇(六)maven整合SSM

    写在前面的话   承接前文<Spring+SpringMVC+MyBatis+easyUI整合基础篇(五)讲一下maven>,本篇所讲述的是如何使用maven与原ssm项目整合,使得一个普 ...

  3. Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

    写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...

  4. Spring+SpringMVC+MyBatis+easyUI整合基础篇(十一)SVN服务器进阶

    日常啰嗦 上一篇文章<Spring+SpringMVC+MyBatis+easyUI整合基础篇(十)SVN搭建>简单的讲了一下SVN服务器的搭建,并没有详细的介绍配置文件及一些复杂的功能, ...

  5. Spring+SpringMVC+MyBatis+easyUI整合基础篇(十二)阶段总结

    不知不觉,已经到了基础篇的收尾阶段了,看着前面的十几篇文章,真的有点不敢相信,自己竟然真的坚持了下来,虽然过程中也有过懒散和焦虑,不过结果还是自己所希望的,克服了很多的问题,将自己的作品展现出来,也发 ...

  6. Spring+SpringMVC+MyBatis+easyUI整合基础篇

    基础篇 Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简介 Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试 Spring+S ...

  7. (spring-第7回【IoC基础篇】)BeanDefinition的载入与解析&&spring.schemas、spring.handlers的使用

    报错信息:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http: ...

  8. (spring-第6回【IoC基础篇】)BeanDefinition——实例化Bean之前的第一大利器。

    上节讲了Bean实例化的内部机制,这里再复述一遍: ResourceLoader从系统中加载XML配置信息,并由Resource来表示. BeanDefinitionReader从Resource中读 ...

  9. (spring-第2回【IoC基础篇】)Spring的Schema,基于XML的配置

    要深入了解Spring机制,首先需要知道Spring是怎样在IoC容器中装配Bean的.而了解这一点的前提是,要搞清楚Spring基于Schema的Xml配置方案. 在深入了解之前,必须要先明白几个标 ...

随机推荐

  1. Laravel 实现定时任务

    运行命令schedule run 时laravel会去App\console\kernel.php文件中查找schedule方法,有没有要执行的定时命令 实现流程:首先可以自定义命令并注册命令(参考上 ...

  2. css3中clip属性

    clip 属性用来设置元素的形状.用来剪裁绝对定位元素. 当一幅图像的尺寸大于包含它的元素时,"clip" 属性允许规定一个元素的可见尺寸,这样此元素就会被修剪并显示在这个元素中. ...

  3. Python--关于 join 和 split

    .join() join将 容器对象 拆分并以指定的字符将列表内的元素(element)连接起来,返回字符串(注:容器对象内的元素须为字符类型) >>> a = ['no','pai ...

  4. python中的类变量、实例变量

    类变量,是各个实例共享的资源,就像中央空调,只有一个,但每个房间(实例)均可享用. 实例变量,是每个实例各自分配使用的变量,每个房间(实例)都有一台空调,供自己使用. class handle(obj ...

  5. Linux GDB常用命令一栏

    Linux GDB 常用命令如下: 1.启动和退出gdb (1)启动:gdb ***:显示一段版权说明: (*** 表示可执行程序名) (2)退出:quit.有的时候输入quit后会出现相关提示:类似 ...

  6. poj---(2886)Who Gets the Most Candies?(线段树+数论)

    Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 10373   Acc ...

  7. uva--1339 - Ancient Cipher(模拟水体系列)

    1339 - Ancient Cipher Ancient Roman empire had a strong government system with various departments, ...

  8. android之merge布局

    <merge />标签闪亮登场了.当LayoutInflater遇到这个标签时,它会跳过它,并将<merge />内的元素添加到<merge />的父元素里. 用& ...

  9. QA16复制_新增查询条件,修改批量使用决策

    需求: 增加评估代码,检验类型条件.(检验批中部分检验项目未录结果的检验批显示    注:标准的程序,不支持空结果的查询和使用决策) 1.复制 RQEVAI10 程序 2.因为这是用的QM模块的逻辑数 ...

  10. 使用MediaPlayer和SurfaceView播放视频

    使用VideoView播放视频简单.方便,丹有些早期的开发者更喜欢使用MediaPlayer来播放视频,但由于MediaPlayer主要用于播放音频,因此它没有提供图像输出界面,此时 需要借助于Sur ...