环境准备:

使用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. 超简单!pytorch入门教程(五):训练和测试CNN

    我们按照超简单!pytorch入门教程(四):准备图片数据集准备好了图片数据以后,就来训练一下识别这10类图片的cnn神经网络吧. 按照超简单!pytorch入门教程(三):构造一个小型CNN构建好一 ...

  2. ABP-AsyncLocal的使用

    1.与AsyncLocal对应的是ThreadLocal 2.两种类型 初始赋值 AsyncLocalString.Value = new List { "1" }; AsyncL ...

  3. codefoce 782c

    好久没有更新了,特地来水一水 简单的涂色问题,大佬说基本都是贪心 #include<cstdio> #include<iostream> #include<vector& ...

  4. jenkins+ant+jmeter自动化环境搭建

    jmeter:测试接口的工具,支持java语言: ant:Apache Ant是一个Java库和命令行工具,其任务是将构建文件中描述的进程作为相互依赖的目标和扩展点.只要使用过Linux系统的读者,应 ...

  5. centos 7.3 服务器环境搭建——MySQL 安装和配置

    centos 7.3 服务器环境搭建——MySQL 安装和配置服务器信息如下:服务器:阿里云系统 centos 7.3 (阿里云该版本最新系统)mysql版本:5.7.18 (当前时间最新版本)连接服 ...

  6. python版飞机大战代码简易版

    # -*- coding:utf-8 -*- import pygame import sys from pygame.locals import * from pygame.font import ...

  7. Eclipse配置运行内存

    对于一些大的项目,运行时等待过长可能出现内存溢出现象,需要重新配置IDE运行内存大小,如下: 1.配置Eclipse.ini 如图再改大点: -Xms512m-Xmx512m 2.JDK内存扩大 Wc ...

  8. 你对Java泛型的理解够深入吗?

    泛型 泛型提供了一种将集合类型传达给编译器的方法,一旦编译器知道了集合元素的类型,编译器就可以对其类型进行检查,做类型约束. 在没有泛型之前: /** * 迭代 Collection ,注意 Coll ...

  9. 开源API网关,你选对了么?

    开源API网关,你选对了么? api网关的本质 不用扯那么多,也不用画图,一句话说清楚 api网关:流量总入口,得以集中控制! 就这么简单 api网关协议上最基本要支持HTTP 和 WebSocket ...

  10. 关闭Win10 445端口

    这次勒索病毒利用了NSA黑客工具包中的“永恒之蓝”0day漏洞,通过电脑445端口(文件共享<普通用户基本用不到这个端口,可以关闭>)在内网进行蠕虫式感染传播,为了防止内网感染,建议用户关 ...