上节讲了Bean实例化的内部机制,这里再复述一遍:

  1. ResourceLoader从系统中加载XML配置信息,并由Resource来表示。
  2. BeanDefinitionReader从Resource中读取配置信息,把配置文件中的<bean>解析成一个BeanDefinition对象,然后把BeanDefinition对象放到BeanDefinitionRegistry注册表中。
  3. 容器从BeanDefinitionRegistry注册表中扫描出Bean工厂后处理器的Bean(该Bean实现了BeanFactoryPostProcessor),用这个工厂后处理器来加工BeanDefinitionRegistry注册表中的所有BeanDefinition对象。具体做了两件事:
    1.   对使用到<bean>元素的占位符的Bean进行解析,把占位符转换成具体值,从而把半成品的BeanDefinition对象转为成品的对象。
    2.   扫描BeanDefinitionRegistry注册表中的所有BeanDefinition对象,通过java反射机制找出所有属性编辑器的Bean(实现了PropertyEditor的Bean),然后把它放到属性编辑器注册表中(PropertyEditorRegistry)。
  4. 容器从BeanDefinitionRegistry中取出加工过的BeanDefinition,并调用InstantiationStrategy着手bean的实例化工作。
  5. 在实例化Bean时,Spring容器使用BeanWrapper对Bean进行封装,BeanWrapper结合BeanDefinition以及属性编辑器完成Bean属性的设置工作。
  6. 利用容器中注册的Bean后处理器(该Bean实现了BeanPostProcessor)对第五步生成的Bean进行后续加工。

从实例化的过程中可以看出,BeanDefinition起到中流砥柱的作用。因为BeanDefinition是配置文件<bean>元素标签在容器中的内部表示。比如,<bean>标签在XML中有class,scope,lazy-init等属性,那么在BeanDefinition中则有相应的beanClass,scope,lazyInit属性等。

BeanDefinition接口的继承结构如图:

顶级的BeanDefinition其实是个接口,下面的AbstractBeanDefinition实现了这个接口,而最下面的ChildBeanDefinition和RootBeanDefinition分别继承了AbstractBeanDefinition。来看一个XML配置:

  <!-- 父子<bean> -->
<bean id="car0" class="com.baobaotao.tagdepend.Car"
p:brand="红旗CA72" p:price="2000.00" p:color="黑色"
abstract="true"/> <bean id="car3" parent="abstractCar">
<property name="color" value="红色"/>
</bean>

car3继承了car0,对应继承结构图,car3使用的是ChildBeanDefinition,car0使用的是RootBeanDefinition,也就是说,car3的属性多于car0,而不管是car3还是car0,它们都有共性(即使配置文件中没写,也是隐形存在的,比如上面讲的scope,lazyInit等),这些共性将提取在AbstractBeanDefinition中。如果<bean>标签没有继承关系,那么它将使用默认的RootBeanDefinition,在2.5版本之后加了一个GenericBeanDefinition,因为自身优势而成为默认的使用类。

下面是BeanDefinition的API:(在线文档:http://tool.oschina.net/apidocs/apidoc?api=Spring-3.1.1)

在方法概述中,我们可以看到这个接口中定义了所有<bean>属性的方法接口,比如singleton、prototype,lazyInit等。

下面是AbstractBeanDefinition的结构图和API:

由于API里的方法很多,我截取几个例子:

这些get方法是获取共性类的属性值,实际上,共性属性的默认值在定义成员变量时就已经默认给定了,请看代码:

 private volatile Object beanClass;

     private String scope = SCOPE_DEFAULT;

     private boolean singleton = true;

     private boolean prototype = false;

     private boolean abstractFlag = false;

     private boolean lazyInit = false;

     private int autowireMode = AUTOWIRE_NO;

     private int dependencyCheck = DEPENDENCY_CHECK_NONE;

     private String[] dependsOn;

     private boolean autowireCandidate = true;

     private boolean primary = false;

上面代码截取的是AbstractBeanDefinition的源码,可以看到许多<bean>标签的属性默认值。

一开始创建的BeanDefinition由于占位符的原因是个半成品,需要用Bean工厂后处理器对Bean进行处理,处理完之后由InstantiationStrategy对BeanDefinition进行实例化。后面我们会详细介绍InstantiationStrategy。

BeanDefinition是如何创建的,XML又是如何被解析的?这些问题需要深入到源码中去寻求答案,在讲完IoC部分之后,我将对源码进行剖析,深入探究其奥妙,希望大家继续支持并关注我的博客。

(spring-第6回【IoC基础篇】)BeanDefinition——实例化Bean之前的第一大利器。的更多相关文章

  1. (spring-第9回【IoC基础篇】)BeanFactoryPostProcessor,实例化Bean之前的第二大利器

    继承结构图如上.在加载XML,注册bean definition之后,在实例化bean definition之前,必要的时候要用到BeanFactoryPostProcessor.它负责把XML中有些 ...

  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-第2回【IoC基础篇】)Spring的Schema,基于XML的配置

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

  8. (spring-第5回【IoC基础篇】)spring容器从加载配置文件到实例化bean的内部工作机制

    前面讲过,spring的生命周期为:实例化前奏-->实例化-->实例化后期-->初始化前期-->初始化-->初始化后期-->bean的具体调用-->销毁前-- ...

  9. (spring-第4回【IoC基础篇】)spring基于注解的配置

    基于XML的bean属性配置:bean的定义信息与bean的实现类是分离的. 基于注解的配置:bean的定义信息是通过在bean实现类上标注注解实现. 也就是说,加了注解,相当于在XML中配置了,一样 ...

随机推荐

  1. 6/3 Sprint2 看板和燃尽图

  2. 项目文件包含 ToolsVersion="12.0" 设置,但此工具集未知或缺失。

    项目属性(Alt+F7),再点常规,常规中有个平台工作集,把V120改成V110或者v100,然后就能正常运行了.

  3. mvc伪静态<四> 伪静态后静态页面或者引用的css和图片失效

    引用的css和图片失效的解决办法 把样式引用文件的相对路径改成绝对路径就可以了 比如原先的引用路径为:<link href="~/Content/css/style.css" ...

  4. override和overload的区别

    override(重写,覆盖) 1.方法名.参数.返回值相同. 2.子类方法不能缩小父类方法的访问权限. 3.子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常). 4.存在于父类和子类之 ...

  5. 玩转linux文件(重点)

    一.几个主要的操作 mkdir—创建目录 cp—复制文件和目录 mv——移动/重命名文件和目录 rm——删除文件和目录 ln——创建硬链接和软链接 二.几个考点: 通配符 硬链接和软链接(符号链接) ...

  6. JavaScript实现冒泡排序、快速排序、插入排序

    JavaScript实现冒泡排序.快速排序.插入排序 时间:2014-01-09 18:05:51  来源:  作者:胡晗 冒泡排序的基本思想:所谓冒泡就是泡泡一个一个往上冒,让体积最轻的泡泡浮在最上 ...

  7. lucene索引文件格式

    转自:http://blog.csdn.net/whuqin 本文介绍下lucene生成的索引有哪些文件组成,每个文件包含了什么信息.基于Lucene 4.10.0. 数据结构 索引(index)包含 ...

  8. windows下phpstorm的快捷键

    ctrl+shift+n查找文件 ctrl+shift+f 在一个目录里查找一段代码(ctrl+f的升级版) ctr+shift+r 在一个目录里查找一段代码并替换(ctrl+r的升级版) CTRL+ ...

  9. 这是BUG吗?

    百度首页的控制台里,有一段招聘信息,想必大家都知道吧,点击里面的链接地址跳到了百度招聘页面然后就发现了这个:,如果这不是BUG的话,那用户体验真是不好

  10. iOS各种动画效果

    ios各种动画效果 最普通动画: //开始动画 [UIView beginAnimations:nil context:nil];  //设定动画持续时间 [UIView setAnimationDu ...