返回
Spring源码剖析4:懒加载的单例Bean获取过程分析
百科(权威知识源 · 考试范围)
作者:管理员最后更新:2026/9/4 19:01:02审核:管理员

前言

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

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

   //这样来加载配置文件    
   XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml")); 

       (1)XmlBeanFactory 继承 AbstractBeanDefinitionReader ,使用ResourceLoader 将资源文件路径转换为对应的Resource文件。

       (2)通过DocumentLoader 对 Resource 文件进行转换,将 Resource 文件转换为 Document 文件。

       (3)通过实现接口 BeanDefinitionDocumentReader 的 DefaultBeanDefinitionDocumentReader 类对Document 进行解析,并且使用 BeanDefinitionParserDelegate对Element进行解析。

step1:

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

  Resource resource = new ClassPathResource("application.xml");
  InputStream in = resource.getInputStream();

step2:

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

      调用XmlBeanDefinitionReader 的 loadBeanDefinitions()方法进行加载资源:

      (1) 对Resource资源进行编码

      (2) 通过SAX读取XML文件来创建InputSource对象

      (3) 核心处理

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

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

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

     869effccb2e4f7b69e0b53d17fe0a2b50044d61b

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

            /*Register the bean definitions contained in the given DOM document/

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

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

核心方法:  <font color="#FF0000">documentReader.registerBeanDefinitions(doc, createReaderContext(resource));</font>

<font color="#FF0000">46ca5d8a7167fb010024f79e1f334820d7d2080a</font>

<font color="#FF0000">开始解析:</font>

<font color="#FF0000">43eb5d219f00c7b5c99c0eed0828b9ff2550af41</font>


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

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

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

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

对于默认标签的解析:

对Bean 配置的解析:

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);  返回BeanDefinitionHolder

f163a5df0d4ea8e105526fa7ef39547a1c188047

b93c6e1209359777b877f17e203e6226a269f4e0

这边代码大致看下来:

  1. 提取元素中的id和name属性
  2. 进一步解析将其他属性封装到 BeanDefinition 的实现类中
  3. 如果没有指定beanName 变使用默认规则生成beanName
  4. 封装类BeanDefinitionHolder

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

      BeanDefinition是一个接口,对应着配置文件中<bean>里面的所有配置,在Spring中存在着三个实现类:

      在配置文件中,可以定义父<bean>和子<bean>,父<bean>是用RootDefinition来表示,子<bean>是用ChildBeanDefinition来表示。

      Spring 通过BeanDefiniton将配置文件中的<bean>配置信息转换为容器内部表示,并且将这些BeanDefinition注册到BeanDefinitonRegistry中。

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

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

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

考试信息
通过标准满分(错一道即与满分无缘,可把整卷答完看解析;重考不限次数)
时间限制不限时
单卷抽题数10 题
成绩窗口2026-09-14 ~ 2026-09-20
积分学费10 积分
支付方式满分后用积分支付(自主决定)
用积分支付:成绩长期保留,参与排名,积分学费含平台资助池;不支付:成绩保留至窗口截止后清空
积分无充值通道;积分不足 10 时,平台自动发放 100 积分。积分不可提现、不可转让、无现金价值。
排行榜(窗口期最短满分用时 · 前 0 名)
当前窗口(2026-09-14 ~ 2026-09-20)

该窗口暂无满分记录

课程(免费学习 · 共 0 门)

暂无课程

登录后可查看我的出题、测试记录并参加满分考试