前言

在前一篇文章:创建 IoC 容器的几种方式中,介绍了四种方式,这里以 AnnotationConfigApplicationContext 为例,跟进代码,看看 IoC 的启动流程。

入口

从 JavaConfig 中加载配置的 AnnotationConfigApplicationContext 启动方式如下:

进去之后发现构造其实是调用的当前无参构造。

所以在启动时也可以直接声明无参构造,改写为下面这种:

public class AnnotationConfigApplicationTest {

	public static void main(String[] args) {

		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

		context.register(JavaConfig.class);
context.refresh(); System.out.println(context.getBean(UserComponent.class)); }
}

今天就研究研究无参构造这一部分究竟做了什么逻辑!

无参构造

其中的 StartupStep 是 5.3 新增的类,看代码注释的意思是:表示用来记录启动过程中的一些指标信息等。暂时不做研究。

主要研究红框部分!注意,这一块并不代表只有红框部分

因为 AnnotationConfigApplicationContext 继承了 GenericApplicationContext,所以会先执行父类的构造方法。

所以这里会创建一个 DefaultListableBeanFactory 的容器。

DefaultListableBeanFactory

虽然说 Spring 的 BeanFactory 定义了容器的基础概念、接口方法等,但是 DefaultListableBeanFactory 才是一个真正可以 new 出来的具体的容器,当然也可以暂且称之为 bean 工厂。

下面来看一下 DefaultListableBeanFactory 里面都有什么?

DefaultListableBeanFactory 里面会初始化很多参数,其中重点关注的是下面两个参数:

/** Map of bean definition objects, keyed by bean name. */
// BeanDefinition 的存储 Map 其中 key 为 beanName
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); /** List of bean definition names, in registration order. */
// BeanName 的集合
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

其中 BeanDefinition 描述了一个 bean 实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。

对应的 beanDefinitionMap 就是存储的初始化的 beanName 和 BeanDefinition。

至于 BeanDefinition 具体内容,下一节再做介绍。

总结

通过上面的阅读,可以在初始化流程中增加一部分模块,即实例化 DefaultListableBeanFactory

再回顾一下 DefaultListableBeanFactory 的概念。

DefaultListableBeanFactory:

Spring 的 ConfigurableListableBeanFactory 和 BeanDefinitionRegistry 接口的默认实现:基于bean定义元数据的成熟bean工厂,可通过后处理器进行扩展。

重点需要把握的是 DefaultListableBeanFactory 内部定义了 BeanDefinition 的 Map。

结束语

本文从入口开始,进入到构造,主要介绍了 DefaultListableBeanFactory 的创建,及创建时初始化了一堆参数。

考虑到文章篇幅问题,尽量避免大段大段的贴代码以及注释,有兴趣的小伙伴可以试着自己搭建源码构建环境,然后 Debug 走一走,这样也可以互相探讨,共同学习。

笔者也是刚开始阅读学习源码,不足之处,希望多多指正。

相关推荐

Spring 源码学习 04:初始化容器与 DefaultListableBeanFactory的更多相关文章

  1. spring源码学习笔记之容器的基本实现(一)

    前言 最近学习了<<Spring源码深度解析>>受益匪浅,本博客是对学习内容的一个总结.分享,方便日后自己复习或与一同学习的小伙伴一起探讨之用. 建议与源码配合使用,效果更嘉, ...

  2. Spring源码学习之IOC容器实现原理(一)-DefaultListableBeanFactory

    从这个继承体系结构图来看,我们可以发现DefaultListableBeanFactory是第一个非抽象类,非接口类.实际IOC容器.所以这篇博客以DefaultListableBeanFactory ...

  3. 【spring源码分析】IOC容器初始化(总结)

    前言:在经过前面十二篇文章的分析,对bean的加载流程大致梳理清楚了.因为内容过多,因此需要进行一个小总结. 经过前面十二篇文章的漫长分析,终于将xml配置文件中的bean,转换成我们实际所需要的真正 ...

  4. 【spring源码分析】IOC容器初始化(七)

    前言:在[spring源码分析]IOC容器初始化(六)中分析了从单例缓存中加载bean对象,由于篇幅原因其核心函数 FactoryBeanRegistrySupport#getObjectFromFa ...

  5. 【spring源码分析】IOC容器初始化(十)

    前言:前文[spring源码分析]IOC容器初始化(九)中分析了AbstractAutowireCapableBeanFactory#createBeanInstance方法中通过工厂方法创建bean ...

  6. Spring源码学习-容器BeanFactory(四) BeanDefinition的创建-自定义标签的解析.md

    写在前面 上文Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签对Spring默认标签的解析做了详解,在xml元素的解析中,Spri ...

  7. Spring源码学习-容器BeanFactory(三) BeanDefinition的创建-解析Spring的默认标签

    写在前面 上文Spring源码学习-容器BeanFactory(二) BeanDefinition的创建-解析前BeanDefinition的前置操作中Spring对XML解析后创建了对应的Docum ...

  8. 【spring源码分析】IOC容器初始化——查漏补缺(一)

    前言:在[spring源码分析]IOC容器初始化(十一)中提到了初始化bean的三个步骤: 激活Aware方法. 后置处理器应用(before/after). 激活自定义的init方法. 这里我们就来 ...

  9. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

随机推荐

  1. configfs_sample.c 理解

    1. 编译运行 代码从如下链接获得: https://github.com/torvalds/linux/blob/master/samples/configfs/configfs_sample.c ...

  2. python机器学习卷积神经网络(CNN)

    卷积神经网络(CNN) 关注公众号"轻松学编程"了解更多. 一.简介 ​ 卷积神经网络(Convolutional Neural Network,CNN)是一种前馈神经网络,它的人 ...

  3. 联发科Mediatek工业路由芯片上网稳定低功耗的Router模块WiFi中继——无线AP定制方案

    Router模块又名路由器模块,是指将路由器的接口类型及部分扩展功能是可以根据实际需求来进行无线接入服务,允许其他无线设备接入,通过局域无线端或联网远程端,进行数据访问,对无线设备进行远程控制.常见的 ...

  4. 14 RPC

    14 RPC RPC(Remote Procedure Call Protocol)--远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些 ...

  5. Android基础——项目的文件结构(三)

    Android基础--项目的文件结构(三) 代码源文件夹与资源文件夹 [注]此项目文件结构仅限于Android Studio下的Android项目!!! 在一个Android项目中,代码源文件夹有4个 ...

  6. Spider--补充--Re模块_1

    # @ Author : Collin_PXY # 正则表达式: import re # 1,分步写法: # 1)rule.search(string) pattern='各小区' rule=re.c ...

  7. 这个Map你肯定不知道,毕竟存在感确实太低了。

    这是why哥的第 75 篇原创文章 从Dubbo的优雅停机说起 好吧,其实本文并不是讲 Dubbo 的优雅停机的. 只是我在 Dubbo 停机方法 DubboShutdownHook 类中,看到了这样 ...

  8. 预训练模型——开创NLP新纪元

    预训练模型--开创NLP新纪元 论文地址 BERT相关论文列表 清华整理-预训练语言模型 awesome-bert-nlp BERT Lang Street huggingface models 论文 ...

  9. C/C++中内存对齐问题的一些理解(转)

    内存对齐指令 一般来说,内存对齐过程对coding者来说是透明的,是由编译器控制完成的 如对内存对齐有明确要求,可用#pragma pack(n)指定,以n和结构体中最长数据成员长度中较小者为有效值 ...

  10. vue 切换主题(换肤)功能

    一:先写好两个css样式放在static文件夹中 二:在index.html中添加css link链接 <link rel="stylesheet" id="sty ...