Spring源碼閱讀之準備篇

引言

 目前,在以Java語言主導的項目中,我們會使用各種各樣的框架來快速搭建應用,尤其在Java web項目中,我們會經常見到Spring的身影,大部分人只知道怎麼使用它,但是不知道它真正的運行原理。本篇文章就來揭祕一下Spring框架的整體面容

我想很多同學和我一樣,在學習閱讀源碼前都或多或少有些疑問,在這裏簡單總結一下常見的問題。

  1. 看源碼既費精力又無聊有啥用呢?

  2. 看完源碼對我到底有些好處呢?

  3. 源碼從那開始讀?怎麼讀?

  4. Spring容器啓動整體流程?

帶着這幾個問題,來看看閱讀源碼是如何讓我們受益的?

01

讀源碼有啥用?

從我自己的角度理解,工作一段時間以後,還是在做着重複的CRUD操作,當遇到一些比較怪異的線上故障的時候,不能像別人一樣快速定位問題,總是沒有頭緒,眉毛鬍子一把抓;遇到這樣的問題多數是因爲對運行的系統理解的深度不夠,只知其表。所以針對這種情況,我覺得應該深入底層去理解其背後的運行原理是至關重要的。

02


讀源碼的收益是啥?

從我自己現在的體會來講,主要有如下:

  • 對系統整體的運行輪廓有一個比較清晰的認知,寫代碼更加遊刃有餘

  • 學習一些框架優秀的設計思想

  • 爲跳槽做一些知識儲備

03


源碼從那開始讀?

這個就比較簡單了,以Spring源碼爲例。首先下載好源碼包,寫一些簡單的測試用例,利用強大的debug功能調試起來,屢試不爽。在後面的源碼閱讀都會採用這種辦法來“偷窺”其真容

04


Spring的IoC“輪廓”?

解決了我們的基本困惑之後,進去我們的正題,Spring到底是怎麼運行起來的呢?在解答這個問題之前,我們先從宏觀上看下Spring的“輪廓”,防止在讀源碼的時候不會一頭扎進去出不來,導致很快就放棄了自己當初信誓旦旦立下的flag。我以Spring5.0.7爲例展開。大家可以選擇一個版本去閱讀,整體流程上不會有太大的出入。下面附上我整理的Spring的流程圖(畫的不好,還請見諒,文末附上搭建測試工程用到的核心依賴配置文件)

對於Spring啓動及bean實例化的整體流程如上圖,大家先做一個簡單的瞭解。每一步的工作也寫明瞭,需要注意的是,比較重要的四步我使用了紅色的橢圓標明瞭。

Spring的IoC全名是 Inversion of Control,即控制反轉,大白話來講就是由原來我們自己親手new對象的工作交給了Spring來幫我們做了,我們只在需要指定對象的時候找Spring容器去拿就好了,麼簡單。

比較重要的幾個方法我在這裏在列一下:

  • obtainFreshBeanFactory(),其作用是創建Spring容器的工廠,並解析配置文件構建相應的BeanDefinition對象(BeanDefinition會貫穿整個源碼閱讀,在這裏我們把它就叫做Bean定義,bean對象就是用它來實例化的)

  • invokeBeanFactoryPostProcessors(),其作用是調用所有實現了BeanFactoryPostProcessor接口或者是BeanDefinitionRegistryPostProcessor子接口的類,簡單理解就是修改BeanDefinition定義的即可

  • registerBeanPostProcessors(),其作用是將實現了BeanPostProcessor接口的類註冊到Spring容器中,在後面Bean實例初始化前後的時候調用其實現,簡單理解就是要在bean實例初始化前後做一些增加功能即可

  • finishBeanFactoryInitialization(),其作用是創建所有非懶加載(非懶加載的意思就是提前加載好方便;相對應的是懶加載,就是在要使用的)

     

總結

本文主要闡明閱讀源碼能給我們帶來哪些收益,以及Spring容器啓動的整體流程概覽。下一篇文章我們將會展開如何debug進入源碼及第一個重要方法obtainFreshBeanFactory()的實現細節。堅持閱讀下去,我會盡自己的努力以最直白的話去闡明Spring的流程。最後歡迎提出意見,共同進步。

附件

maven構建Spring源碼調試工程用到的依賴,持續更新中
<dependencies>
    <!-- spring 核心組件中的4個依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.0.7.RELEASE</version>
    </dependency>


    <!-- 單元測試Junit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
  </dependencies>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章