前言

在前一篇文章:创建 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. scrapy反反爬虫

    反反爬虫相关机制 Some websites implement certain measures to prevent bots from crawling them, with varying d ...

  2. 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

    本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...

  3. 找出"吸血鬼数"(Java)

    吸血鬼数是指位数为偶数的数字,可以由一 对数字相乘而得到,而这对数字各包含乘积的一半 位数的数字,其中从最初的数字中选取的数字可以任意排序.以两个0结尾的数字是不允许的,例如,下列数字都是 " ...

  4. leetcode131:letter-combinations-of-a-phone-number

    题目描述 给出一个仅包含数字的字符串,给出所有可能的字母组合. 数字到字母的映射方式如下:(就像电话上数字和字母的映射一样) Input:Digit string "23"Outp ...

  5. nginx负载均衡基本配置和日志按天写

    简单记录一下. upstream dynamic_pools{        server 127.0.0.1:8080;    } #动态命令转交给后端        location /api   ...

  6. 内核搞笑的bug不少

  7. linux 协议栈 实现--编码小知识分析

    unlikely 以及likely 作用: rcu_read_lock  以及rcu_read_unlock 作用: rcu_dereference .rcu_dereference_protecte ...

  8. python之 栈与队列

    忍不住想报一句粗口"卧槽"这尼玛python的数据结构也太特么方便了吧 想到当初学c语言的数据结构的时候,真的是一笔一划都要自己写出来,这python尼玛直接一个模块就ok 真的是 ...

  9. Linux 笔记1

    linux netstat -an | grep 8081 查看端口进程 window netstat -ano|findstr "1433" taskkill -pid ** - ...

  10. mon的稳定性问题

    MON的稳定性问题: mon的选举风暴影响客户端IO LevelDB的暴涨 频繁的客户端请求的DDOS mon选举风暴: monmap会因为mon之间或者mon与客户端之间网络的影响或者消息传递的异常 ...