前言
BeanFactory
是spring boot
最重要的核心组件,当然也是spring boot
非常基础的组件,所以梳理清楚BeanFactory
的源码才是梳理清楚Spring boot
源码的关键。前天,我们分享了beanDefinitionNames
和beanDefinitionMap
的初始化过程,虽然过程中有涉及到beanFactory
的相关知识点,但是关于beanFactroy
我们还没有正式地分析过它,关于它的初始化过程,也是一无所知,为了更系统地了解beanFactory
,从今天开始我们开始更系统地分析beanFactory
的相关源码,下面我们就先来看下BeanFactory
的初始化过程。
BeanFactory初始化
今天我们依然是从一张时序图开始讲起,下面这张时序图就是spring boot
容器的BeanFactory
初始化过程,beanFactory
初始化其实是和容器的初始化同时完成的,它也是容器初始化过程中的重要一步:

在上面的时序图中,最关键的内容就是AnnotationConfigServletWebServerApplicationContext
的实例化过程,这里面涉及到java
类的初始化流程:创建子类时,必须先调用父类无参构造方法,所以AnnotationConfigServletWebServerApplicationContext
是在所有父类实例化完成后,才完成它自己的实例化过程的。下面我们就来看AnnotationConfigServletWebServerApplicationContext
的初始化流程。
createApplicationContext
在debug
的过程中,我发现 BeanFactory
在容器被创建后就已经被初始化,这也就是说BeanFactory
其实是在spring boot
容器创建过程中被初始化的,所以我们今天主要就是研究容器创建过程,也就是createApplicationContext()
方法:

关于createApplicationContext
这个方法,我们前面已经展示过了,它的作用就是通过反射创建容器实例:

AnnotationConfigServletWebServerApplicationContext实例化
通过跟踪代码,最终可以确认,调用的是AnnotationConfigServletWebServerApplicationContext
无参构造方法:

所以下面就是对AnnotationConfigServletWebServerApplicationContext
的实例化,由于容器这块继承关系比较复杂,所以实例化顺序也比较复杂。
容器实例化
虽然各位小伙伴可能很清楚java
对象实例化过程,但是我觉得还是有必要再补充说明下。在有继承关系的java
对象实例化过程中,如果当前类继承了父类,在实例化当前类时,先要调用父类的无参构造方法(就算不指定,也会隐式调用)。所以,在这里初始AnnotationConfigServletWebServerApplicationContext
时,会先调用它的父类无参构造方法,下面是AnnotationConfigServletWebServerApplicationContext
的继承关系,看起来确实很复杂:

在跟踪代码的过程中,最终我确认BeanFactory
是在GenericApplicationContext
的无参构造方法中完成初始化的,也就是AnnotationConfigServletWebServerApplicationContext
父类的父类的父类:

所以初始化的过程就是,AnnotationConfigServletWebServerApplicationContext
的无参构造方法中先调用ServletWebServerApplicationContext
的无参构造方法,ServletWebServerApplicationContext
的无参构造方法中先调用GenericWebApplicationContext
的无参构造方法,GenericWebApplicationContext
的无参构造方法先调用GenericApplicationContext
的无参构造方法(无限套娃)……
知识扩展
后续的调用这里就直接省略了,因为他们和BeanFactory
没有关系,而且因为继承关系过于复杂,所以这里我们要尽可能简单。在这里所有的初始化操作中,调用父类构造方法始终是首先被执行的,也必须首先被执行(首先调用父类的无参构造方法),这也就是为什么我们在写类的有参构造方法的时候,如果父类没有无参构造方法时,必须显式调用父类有参构造方法,且必须放在第一行的原因:



总结
截止到今天,我们已经梳理清楚beanFactory
的两块内容,一个是beanDefinitionNames
和beanDefinitionMap
,他们都是beanFactory
的核心属性,另一块就是我们今天的BeanFactory
的初始化,下一步应该还是会进一步深挖beanFactory
的相关知识点,因为从一开始我的想法就是要找到spring boot
包扫描和实例化bean
的相关逻辑,但到目前为止还没有理清楚这一块的逻辑和流程,不过我相信很快我们就能完成这个目标了,因为我们的每一步都在更靠近目标……
– END –
原文始发于微信公众号(云中志):spring-boot源码分析之BeanFactory · 贰
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/40511.html