环境准备:

使用spring5.1.6版本

1 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.hou.spring.bean.User"></bean>
</beans>

2 测试类

public class BeanTest{

    @Test
public void beanTest(){
//spring4之后XmlBeanFactory被废弃,改用以下方式
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
User user = (User) applicationContext.getBean("user");
System.out.println(user);
}
}

然后点进去源码,跟着一步步debug来分析:

1 构造器调用:

ClassPathXmlApplicationContext的构造器中调用类同名方法:

点击this跳转到初始化方法:

2 super()方法是一直到父类AbstractApplicationContext中,将ApplicationContext的环境属性设置给本类的环境属性,包括一些profile,系统属性等

3 setConfigLocations方法也是调用父类方法,将xml配置文件名字设置给父类的String数组属性

4 refresh() 方法,所有的逻辑其实都在这个方法里面进行,主要分析这个方法:

5 prepareRefresh主要还是环境属性的一些初始化,主要看第二步:

// Tell the subclass to refresh the internal bean factory. 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

点进去obtainFreshBeanFactory:

6 首先看refreshBeanFactory方法,注意,如果不知道是哪个子类的话,可以跟着debug断点走:

主要分为这么几个步骤:

一 首先判断本类的DefaultListableBeanFactory属性是否为null,如果不为null,就先清除一写跟Bean有关的Map或者List等属性集合

二 将BeanFactory设置为null,序列化id设置为null,
三 创建DefaultListableBeanFactory,这个类很重要,是springBean初始化的核心类,
四 对beanFactory进行设置,bean注册等操作,最后将beanFactory赋值给本类的beanFactory属性

7 customizeBeanFactory(beanFactory); 只做了两件事:

8 loadBeanDefinitions:   Bean的注册主要是在这一步进行,下面进行分析,这个方法有5个子类实现:

我写的测试类不是Web项目,所以会进入AbstractXmlApplicationContext这个类里的方法,如果是Web项目,会走XmlWebApplicationContext:

首先创建XmlBeanDefinitionReader:xml配置读写器然后设置环境属性以及资源加载器为ClassPathXmlApplicationContext,这个加载器很重要,后面会用到

接着初始化读取器: initBeanDefinitionReader,最后加载Bean

8 initBeanDefinitionReader

这个方法默认实现是空的,允许用户自定义实现读取器的定制化,需要实现接口,可以设置xml解析完成校验,定制化解析器等

9 loadBeanDefinitions: 加载Bean信息,点进去:

这个方法主要是加载类的两个资源属性,Resource[] 和xml位置信息,主要看加载Xml的:

10 reader.loadBeanDefinitions(configLocations);

循环加载xml文件的Bean返回Bean总个数,查看加载方法:

11 查看这个load方法:

这里需要注意第八步设置的加载器,查看加载器的时序图:

因为有继承关系所以直接进if分支,继续分析if分支代码:

主要步骤:

1 获取加载器中的Resource[] 数组

2 加载资源中的Bean,返回加载数量

12 查看loadBeanDefinitions,循环加载了所有的资源,返回总数

13 查看单个加载方法loadBeanDefinitions,主要看中间一段逻辑:

这里对正在解析的xml资源放入ThreadLocal中,保证只有本次线程可以访问,加载完之后再移除

13 查看doLoadBeanDefinitions(inputSource, encodedResource.getResource());

												

spring源码系列(十): 读取xml入口类 ClassPathXmlApplicationContext 分析的更多相关文章

  1. Spring源码系列 — Bean生命周期

    前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...

  2. Ioc容器BeanPostProcessor-Spring 源码系列(3)

    Ioc容器BeanPostProcessor-Spring 源码系列(3) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Io ...

  3. Ioc容器beanDefinition-Spring 源码系列(1)

    Ioc容器beanDefinition-Spring 源码系列(1) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器 ...

  4. AOP执行增强-Spring 源码系列(5)

    AOP增强实现-Spring 源码系列(5) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器BeanPostProc ...

  5. Spring源码系列 — 注解原理

    前言 前文中主要介绍了Spring中处理BeanDefinition的扩展点,其中着重介绍BeanDefinitionParser方式的扩展.本篇文章承接该内容,详解Spring中如何利用BeanDe ...

  6. Spring源码系列 — BeanDefinition扩展点

    前言 前文介绍了Spring Bean的生命周期,也算是XML IOC系列的完结.但是Spring的博大精深,还有很多盲点需要摸索.整合前面的系列文章,从Resource到BeanDefinition ...

  7. Spring源码系列 — BeanDefinition

    一.前言 回顾 在Spring源码系列第二篇中介绍了Environment组件,后续又介绍Spring中Resource的抽象,但是对于上下文的启动过程详解并未继续.经过一个星期的准备,梳理了Spri ...

  8. 事件机制-Spring 源码系列(4)

    事件机制-Spring 源码系列(4) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器BeanPostProcess ...

  9. Ioc容器依赖注入-Spring 源码系列(2)

    Ioc容器依赖注入-Spring 源码系列(2) 目录: Ioc容器beanDefinition-Spring 源码(1) Ioc容器依赖注入-Spring 源码(2) Ioc容器BeanPostPr ...

随机推荐

  1. Mysql(超级详细)

    Mysql(超级详细) (黑小子-余) 一.Mysql介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理 ...

  2. 在springboot环境下tk-mybatis的使用记录

    1. 新建springboot工程 访问https://start.spring.io/,新建一个springboot工程. 自动生成的工程主要的注意点如下: 1)pom.xml <parent ...

  3. 看完知乎上500条答案,我为大家整理了这21个B站学习类UP主

    原文之前发在我的知乎,转载请注明出处. ​ 虽然,今天算法文章还没更新┏(゜ロ゜;)┛,但还是溜过来跑个题~ 之前看到了博客上有小伙伴在分享自己的B站资源,才突然意识到自己其实也积攒了很多优秀UP的资 ...

  4. CEF编译遇到的问题记录

    在使用vs2015编译cef官方代码的时候遇到很奇怪的问题, 我用官方的demo cefsimple例子程序编译debug版本 可以正常编译打开网页 正常的打开 我把官方的例子单独创建一个新的项目编译 ...

  5. $[NOIp2008]$双栈排序 栈/二分图/贪心

    \(Sol\) 先考虑单栈排序,怎么样的序列可以单栈排序呢?设\(a_i\)表示位置\(i\)是哪个数.\(\exist i<j<k\),都没有\(a_k<a_i<a_j\), ...

  6. UML类图基础

    UML( Unified Modeling Language) 统一建模语言, 它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和 ...

  7. vue-cli3 中 sockjs-node/info?t=报错 的解决方法

    页面突然出现这种报错: 查看Network看到是info接口报错,我项目中没有调用过该项目,然后百度查询sockjs-node/info?t=1562204191563, 首先 sockjs-node ...

  8. java基础之----非空判断

    大家好,第一次写博客,一直想写博客,用于自我总结,也用于帮助新同学成长. 平常我们开发的时候,用到很多非空判断,但是很多同学用到的地方不是很准确,这里,我把自己平时遇到的坑跟大家说说.我废话不多,只想 ...

  9. 关于AWD线下攻防的经验

    备份:     1.备份源码,使用图像化工具连接ssh后,我喜欢用winscp,         找到根目录后,直接右键后台下载就行.           找根目录这里,有时候比赛不给根目录位置,上次 ...

  10. git stash使用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/daguanjia11/article/ ...