初始化容器與 DefaultListableBeanFactory
前言
在前一篇文章:創(chuàng)建 IoC 容器的幾種方式中,介紹了四種方式,這里以 AnnotationConfigApplicationContext 為例,跟進(jìn)代碼,看看 IoC 的啟動(dòng)流程。
1入口
從 JavaConfig 中加載配置的 AnnotationConfigApplicationContext 啟動(dòng)方式如下:
進(jìn)去之后發(fā)現(xiàn)構(gòu)造其實(shí)是調(diào)用的當(dāng)前無參構(gòu)造。
所以在啟動(dòng)時(shí)也可以直接聲明無參構(gòu)造,改寫為下面這種:
- 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));
- }
- }
今天就研究研究無參構(gòu)造這一部分究竟做了什么邏輯!
無參構(gòu)造
其中的 StartupStep 是 5.3 新增的類,看代碼注釋的意思是:表示用來記錄啟動(dòng)過程中的一些指標(biāo)信息等。暫時(shí)不做研究。
主要研究紅框部分!注意,這一塊并不代表只有紅框部分!
因?yàn)?AnnotationConfigApplicationContext 繼承了GenericApplicationContext,所以會(huì)先執(zhí)行父類的構(gòu)造方法。
所以這里會(huì)創(chuàng)建一個(gè) DefaultListableBeanFactory 的容器。
DefaultListableBeanFactory
DefaultListableBeanFactory UML
雖然說 Spring 的 BeanFactory 定義了容器的基礎(chǔ)概念、接口方法等,但是 DefaultListableBeanFactory 才是一個(gè)真正可以 new 出來的具體的容器,當(dāng)然也可以暫且稱之為 bean 工廠。
下面來看一下 DefaultListableBeanFactory 里面都有什么?
在 DefaultListableBeanFactory 里面會(huì)初始化很多參數(shù),其中重點(diǎn)關(guān)注的是下面兩個(gè)參數(shù):
- /** Map of bean definition objects, keyed by bean name. */
- // BeanDefinition 的存儲(chǔ) 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 描述了一個(gè) bean 實(shí)例,該實(shí)例具有屬性值,構(gòu)造函數(shù)參數(shù)值以及具體實(shí)現(xiàn)所提供的更多信息。
對應(yīng)的 beanDefinitionMap 就是存儲(chǔ)的初始化的 beanName 和 BeanDefinition。
至于 BeanDefinition 具體內(nèi)容,下一節(jié)再做介紹。
2.總結(jié)
通過上面的閱讀,可以在初始化流程中增加一部分模塊,即實(shí)例化 DefaultListableBeanFactory
再回顧一下 DefaultListableBeanFactory 的概念。
ConfigurableListableBeanFactory 和 BeanDefinitionRegistry 接口的默認(rèn)實(shí)現(xiàn):基于bean定義元數(shù)據(jù)的成熟bean工廠,可通過后處理器進(jìn)行擴(kuò)展。重點(diǎn)需要把握的是 DefaultListableBeanFactory 內(nèi)部定義了 BeanDefinition 的 Map。
結(jié)束語
本文從入口開始,進(jìn)入到構(gòu)造,主要介紹了 DefaultListableBeanFactory 的創(chuàng)建,及創(chuàng)建時(shí)初始化了一堆參數(shù)。
考慮到文章篇幅問題,盡量避免大段大段的貼代碼以及注釋,有興趣的小伙伴可以試著自己搭建源碼構(gòu)建環(huán)境,然后 Debug 走一走,這樣也可以互相探討,共同學(xué)習(xí)。
本文轉(zhuǎn)載自微信公眾號「程序員小航」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系程序員小航公眾號。