Spring XML默认标签配置解析注册Bean源码分析(一)——概述

1. 引言

        在进入Spring源码分析之前,我们先来看一下Spring框架的总体结构。如下图:

        Spring作为一个分层框架,通过划分多个模块,提供了一系列的功能要素。这些模块基于Core Container(核心容器)构建。本篇围绕Core Container的基础Beans和Core两个模块展开,它们提供了IoC(Inversion of Control控制反转)/DI(Dependency Injection依赖注入)的特性。Core模块提供了Spring框架基本的核心工具类,Beans模块提供了创建和管理bean以及Ioc和DI的相关操作。

        在本篇的内容主要是基于以XML配置Bean的方式来探究Bean的解析与注册。

2. 初识Bean的解析与注册

        以XML配置文件的方式,Spring框架中对Bean的创建大致流程主要包括:

  1. 获取xml配置文件Resource资源;
  2. 将配置文件Resource转换为Document对象;
  3. 将Document解析为BeanDefinition,BeanDefinition是bean实例的抽象描述,也是我们要讲述的核心,所谓Bean的解析与注册,其实就是对BeanDefinition的一系列操作;
  4. 将BeanDefinition注册缓存到一个Map(beanDefinitionMap)中;

        通过Map中的BeanDefinition我们就可以实现后续对Bean的创建和管理等操作,后面我们会逐步展开剖析。本篇关注的焦点在于Spring如何一步步实现从XML配置到BeanDefinition的Map注册。

2.1. Xml配置文件Resource资源获取

        Spring对资源的获取提供了多种方式,这里我们通过Resource接口来获取资源,由于Spring的xml配置文件一般放在类路径下,所以我们使用ClassPathResource来实现。

Resource resource = new ClassPathResource("conf/beans.xml");

        配置文件beans.xml的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="person" class="com.yanglh.beans.Person">
        <constructor-arg name="age" value="29"/>
        <constructor-arg name="fullname" value="yangliehui" />
    </bean>
</beans>

        得到了Resource对象我们就可以读取资源的内容和相关属性信息。关于Spring的ClassPathResource提供的相关功能方法请参考Spring ClassPathResource详解

2.2. 认识DefaultListableBeanFactory

        DefaultListableBeanFactory是Spring中bean加载的核心处理类,是注册和加载bean的默认实现,其类图如下:

        从上图中我们大致可以看到DefaultListableBeanFactory继承了父类/接口的两大基因,分别是XxxBeanFactory和XxxRegistry(这里的重点是BeanDefinitionRegistry)。如果对这两个基因大致概括一下的话,那么XxxRegistry是用来注册和存储管理BeanDefinition(由BeanDefinitionRegistry定义)和bean对象(由XxxBeanRegistry定义)的,其中BeanDefinitionRegistry定义了将BeanDefinition实例缓存于一个Map中的方法。BeanFactory是Bean工厂,用来生产Bean的,我们可以从BeanFactory中获取我们交给Spring管理的Bean对象。

2.3. 认识XmlBeanDefinitionReader

        Xml / BeanDefinition / Reader三个关键字,Xml我们已经知道,就是我们的Bean配置文件。BeanDefinition是Spring中管理的Bean的抽象定义,用来描述Bean对象的。那么Reader是什么?从Xml中读取解析注册BeanDefinition的读取器,负责将Xml资源转换为Document对象、加载BeanDefinition、注册BeanDefinition等,是整个BeanDefinition创建过程中的读取调度中心。
        如果我们把从XxxBeanFactory中getBean得到的对象看成是产品成品的话,那么Resource就是物料清单,XxxReader就是根据将物料清单转换为实际成品原材料BeanDefinition的加工处理调度中心,BeanDefinitionRegistry就是实际成品原材料BeanDefinition进行存储和管理的仓库,XxxBeanFactory就是根据原材料生产和管理产品成品(Bean对象)的工厂。

        用代码实现如下:

// 创建Resource物料清单
Resource resource = new ClassPathResource("conf/beans.xml");

// 创建DefaultListableBeanFactory(含有XxxRegistry和XxxBeanFactory两大基因)
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

/** 
 创建BeanDefinition读取器(BeanDefinition加工处理中心)。并将含有
 XxxRegistry基因的DefaultListableBeanFactory注入,用来存储管理BeanDefinition。
 从XmlBeanDefinitionReader的构造方法:
 public XmlBeanDefinitionReader(BeanDefinitionRegistry registry)中
 我们也能看到它的确需要注入的就是一个Registry。
*/
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

/**
 万事都已俱备,下面我们可以拿着Resource物料清单
 到BeanDefinition加工处理中心(XxxReader)中
 来生产Beandefinition了
*/
reader.loadBeanDefinitions(resource);

// 从Bean工厂中得到我们的Bean成品
Person person = factory.getBean("person",Person.class);

注:以上我们把Bean从xml配置到实际得到Bean对象的流程做了一个大概的抽象的了解,这有助于我们对Spring的这一流程有一个全貌的认识。其实Spring内部做了大量的操作完成了这一流程,有些表述可能并不精确,但是没有关系,接下来我们会走进Spring的源码,以源码精确的理解,去完善丰富和修正我们上面的描述。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值