15

Spring 源码学习 04:初始化容器与 DefaultListableBeanFactory

 3 years ago
source link: https://segmentfault.com/a/1190000038361285
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

ZB7buir.png!mobile

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

入口

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

MfUfU3r.png!mobile

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

rmaY7je.png!mobile

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

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));

    }
}

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

无参构造

zIbQRjJ.png!mobile

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

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

Zj6bYjU.png!mobile

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

Z3UB7nu.png!mobile

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

DefaultListableBeanFactory

2QZjmqr.png!mobile

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

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

YBnyqaB.png!mobile

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

26jIzqM.png!mobile

再回顾一下 DefaultListableBeanFactory 的概念。

DefaultListableBeanFactory:

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

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

结束语

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

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

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK