在前一篇文章:建立 IoC 容器的幾種方式中,介紹了四種方式,這裏以 AnnotationConfigApplicationContext
爲例,跟進代碼,看看 IoC 的啓動流程。java
從 JavaConfig 中加載配置的 AnnotationConfigApplicationContext
啓動方式以下:函數
進去以後發現構造實際上是調用的當前無參構造。學習
因此在啓動時也能夠直接聲明無參構造,改寫爲下面這種:spa
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)); } }
今天就研究研究無參構造這一部分究竟作了什麼邏輯!3d
其中的 StartupStep
是 5.3 新增的類,看代碼註釋的意思是:表示用來記錄啓動過程當中的一些指標信息等。暫時不作研究。code
主要研究紅框部分!注意,這一塊並不表明只有紅框部分!blog
由於 AnnotationConfigApplicationContext
繼承了 GenericApplicationContext
,因此會先執行父類的構造方法。繼承
因此這裏會建立一個 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 走一走,這樣也能夠互相探討,共同窗習。
筆者也是剛開始閱讀學習源碼,不足之處,但願多多指正。