天天看点

spring bean 的加载机制(源码分析)

       xml的读取应该是spring的重要功能,因为spring的大部分功能都是以配置做为切入点的。

       我们在静态代码块中读取配置文件可以这样做:

       (1)xmlbeanfactory 继承 abstractbeandefinitionreader ,使用resourceloader 将资源文件路径转换为对应的resource文件。

       (2)通过documentloader 对 resource 文件进行转换,将 resource 文件转换为 document 文件。

       (3)通过实现接口 beandefinitiondocumentreader 的 defaultbeandefinitiondocumentreader 类对document 进行解析,并且使用 beandefinitionparserdelegate对element进行解析。

step1:

spring bean 的加载机制(源码分析)

     在平常开发中,我们也可以使用resource 获取 资源文件:

step2:

spring bean 的加载机制(源码分析)

      在资源实现加载之前,调用了 super(parentbeanfactory) --  /**ignore the given dependency interface for autowiring.(忽略接口的自动装配功能)*/

      调用xmlbeandefinitionreader 的 loadbeandefinitions()方法进行加载资源:

      (1) 对resource资源进行编码

      (2) 通过sax读取xml文件来创建inputsource对象

      (3) 核心处理

spring bean 的加载机制(源码分析)

       可以很直观的看出来是这个function是在解析xml文件从而获得对应的document对象。

spring bean 的加载机制(源码分析)

      在doloaddocument方法里面还存一个方法getvalidationmodeforresource()用来读取xml的验证模式。(和我关心的没什么关系,暂时不看了~)

      转换成document也是最常用的方法:

spring bean 的加载机制(源码分析)

step3 : 我们已经step by step 的看到了如何将xml文件转换成document的,现在就要分析是如何提取和注册bean的。

            /**register the bean definitions contained in the given dom document*/

spring bean 的加载机制(源码分析)

参数doc是doloadbeandefinitions()方法传进来的  loaddocument 加载过来的。这边就很好的体现出了面向对象的单一全责原则,将逻辑处理委托給单一的类去处理。

在这边单一逻辑处理类是:  beandefinitiondocumentreader

核心方法:  documentreader.registerbeandefinitions(doc, createreadercontext(resource));

spring bean 的加载机制(源码分析)

开始解析:

spring bean 的加载机制(源码分析)

-------------

在spring的xml配置中有两种方式来声明bean:

     一种是默认的:  <bean id = " " class = " " />

     还有一种是自定义的:  < tx : annotation-driven / >

spring bean 的加载机制(源码分析)

通过xml配置文件的默认配置空间来判断:http://www.springframework.org/schema/beans

对于默认标签的解析:

spring bean 的加载机制(源码分析)

对bean 配置的解析:

spring bean 的加载机制(源码分析)

<b>beandefinitionholder bdholder = delegate.parsebeandefinitionelement(ele);  返回beandefinitionholder</b>

<b></b>

spring bean 的加载机制(源码分析)
spring bean 的加载机制(源码分析)

这边代码大致看下来:

  提取元素中的id和name属性

  进一步解析将其他属性封装到 beandefinition 的实现类中

  如果没有指定beanname 变使用默认规则生成beanname

封装类beandefinitionholder

可以先了解一下  beandefinition  这个类的作用。

      beandefinition是一个接口,对应着配置文件中&lt;bean&gt;里面的所有配置,在spring中存在着三个实现类:

spring bean 的加载机制(源码分析)

      在配置文件中,可以定义父&lt;bean&gt;和子&lt;bean&gt;,父&lt;bean&gt;是用rootdefinition来表示,子&lt;bean&gt;是用childbeandefinition来表示。

      spring 通过beandefiniton将配置文件中的&lt;bean&gt;配置信息转换为容器内部表示,并且将这些beandefinition注册到beandefinitonregistry中。

spring容器的beandefinitonregistry就像是spring配置信息的内存数据库,主要是以map的形式保存的。

     因此解析属性首先要创建用于承载属性的实例:

spring bean 的加载机制(源码分析)

然后就是各种对属性的解析的具体方法:

spring bean 的加载机制(源码分析)