分析開源項目源碼,咱們該如何入手分析?(授人以漁)

1 前言

本文接上篇文章跟你們聊聊咱們爲何要學習源碼?學習源碼對咱們有用嗎?,那麼本篇文章再繼續跟小夥伴們聊聊源碼這個話題。html

在工做之餘開始寫SpringBoot源碼分析專欄前,跟小夥伴們聊聊「分析開源項目源碼,咱們該如何入手分析?」這個話題,咱們就隨便扯皮,反正是跟小夥伴們一塊兒學習交流,不必太正式。java

小夥伴們看完本文後,如有本身的源碼閱讀心得能夠在下面進行評論或私聊我進行分享,讓我從小夥伴們身上GET多點源碼閱讀的一些技巧,嘿嘿。web

2 學習開源框架源碼到底難不難?

那麼,先跟小夥伴們聊聊學習開源框架源碼的感覺,請問大家認爲學習開源框架源碼到底難不難?這是一個開放的話題,可謂仁者見仁,智者見智。有一些開源大牛們會說,So easy!;有一些有源碼閱讀習慣且工做多年的小夥伴們會說,還好。;有一些剛開始學習源碼的小夥伴們會說,太難了!。是的,不一樣工做經驗不一樣技術層次的人的回答是不同的。算法

那麼剛開始學習開源項目源碼難不難呢?應該對絕大部分小夥伴們來講應該是偏難的。爲何呢?可能有如下四點緣由spring

  1. 一個能流行起來的成熟的開源項目一定功能齊全,可擴展,而功能齊全可擴展的開源項目一定很複雜,代碼量大。好比Spring5框架的源碼行數達到了六七十萬行,SpringBoot的源碼行數達到了25萬行左右,Dubbo和RocketMQ的源碼行數達到了10萬行。一個成熟的開源項目代碼量這麼多,能夠想象其有多複雜。
  2. 閱讀源碼時,咱們有時候沒法猜透源碼做者當時編碼時的想法。由於在剛開始閱讀源碼的過程當中,咱們確定會遇到很不懂的代碼,不知道做者爲什麼這麼寫,爲什麼在這個位置寫代碼,這些都是很正常的,由於當初做者爲啥這麼寫,多是針對一些比較特殊的業務場景,或者爲了某方面的性能等等,咱們根本沒法猜透。打個不太恰當的比喻,閱讀源碼猜想做者的心思就像當初遇到一個本身喜歡的姑娘,猜想她的心思同樣,好比猜想她喜歡什麼,她的興趣愛好是什麼。其實剛開始閱讀源碼也同樣,有些地方咱們一開始是沒法猜透做者的心思的。
  3. 有些開源框架可能集操做系統知識,數據結構,算法和設計模式於一身。是的,優秀的框架一定是集成了不少設計模式於一身,目前爲止筆者還沒見過哪一種流行的又沒有應用設計模式的框架哈。好比不少框架運用了單例模式,工廠模式,責任鏈模式,裝飾器模式和模板方法模式等,由於使用設計模式能讓框架易於擴展。同時,不乏一些框架應用了一些操做系統層面的知識,這一塊比較底層,相信不少學java的小夥伴沒接觸過。此外,開源框架某些地方會用到數據結構和算法,舉個栗子,好比Dubbo默認有四種負載均衡策略,而每種策略又對應一種算法,其中又數RoundRobinLoadBalance負載均衡策略最複雜,一開始實現RoundRobinLoadBalance負載均衡的方式並不太完美或者說有bug,Dubbo也是重寫過RoundRobinLoadBalance幾回,最終借鑑了Nginx的RoundRobinLoadBalance負載均衡算法apache

    上篇文章《跟你們聊聊咱們爲何要學習源碼?學習源碼對咱們有用嗎?》也說過優秀框架之間的思想都是互相借鑑的,這就是咱們要學習源碼的緣由之一。設計模式

    這裏好像扯的有點遠了,總之這裏要說明的是閱讀優秀框架是有必定難度的。數據結構

  4. 有些開源框架註釋太少也增長了閱讀源碼的難度。說到開源項目註釋,若是咱們閱讀老外寫的的框架源碼可能還好,通常都會有大量註釋,好比Spring框架,能夠說幾乎每一個方法都有註釋,這個就給咱們閱讀源碼起了很大的幫助。不過惟一很差的可能就是英文註釋,閱讀對英語有必定的要求。其實英文註釋還好,遇到不懂的,百度翻一下就行了。其實比較頭疼的就是一些國內優秀的開源框架,其註釋能夠說是不多的,這無疑大大增長了閱讀的難度,甚至有些框架的文檔也不齊全,那就更加GG了。

3 該如何入手去分析開源框架源碼?

前面跟小夥伴們聊了閱讀源碼的難度,千萬不要被嚇慌了。不能否認,剛開始閱讀某個開源項目的源碼是有必定的難度。注意,前面的用詞是剛開始剛開始哈。也就是說若是咱們堅持閱讀源碼的話,養成閱讀源碼是陶冶情操的習慣的話,長期堅持下來再去閱讀其餘項目的源碼,遊刃有餘不敢說,但確定能夠很快入手。mvc

那麼,咱們該如何入手去分析開源框架源碼呢?負載均衡

首先,結合前面所說的閱讀源碼之因此難的緣由,咱們就要有針對性的去克服解決。好比有空多學學設計模式,算法和英語。這些軟實力確實對閱讀源碼有很大幫助。

其次,閱讀源碼的前提是什麼?固然,閱讀源碼是要創建在會使用的基礎上,就像若還不會走路就學騎單車同樣,若連用都不會就去鑽研源碼可能會拔苗助長。

最後,咱們閱讀源碼要注意一些技巧,如今根據自身經歷總結一下相關思路和技巧,以下:

  1. 開始閱讀源碼時,先對框架的模塊及其關係有一個總體的認識。咱們要對框架項目的模塊和目錄要有一個全盤的瞭解,要知道每一個模塊是幹嗎的,而後要了解模塊與模塊之間的關係。

    舉個栗子,好比Dubbo的模塊分包核心的主要有如下八個,以下圖,咱們要知道最基礎的的模塊應該是dubbo-common公共邏輯模塊,這個模塊做爲最基礎的模塊,主要是提供了通用模型和工具類;而後dubbo-remoting是遠程通信模塊,依賴於dubbo-common模塊,至關於Dubbo協議的實現;而dubbo-rpc則是遠程調用模塊,依賴於dubbo-remoting模塊,抽象各類協議,以及動態代理;dubbo-cluster是集羣模塊,依賴於dubbo-rpc模塊,將多個服務提供方假裝爲一個提供方,包括:負載均衡, 容錯,路由等。
    分析開源項目源碼,咱們該如何入手分析?(授人以漁)

  2. 分析源碼先從父類或父接口開始分析。由於父類或者父接口每每表明了一類功能,這些基類或基類接口每每抽象了各個具體子類共有的屬性和行爲,一些比較基礎的方法都在父類中實現,而後留個模板方法給子類去實現便可(模板方法的應用)。

    舉個栗子,這裏仍是拿Dubbo的負載均衡來講吧,以下圖,LoadBalance是各類負載均衡策略的超級接口,定義了 select 方法用來實現選擇哪臺機器;而後AbstractLoadBalance是一個抽象類,實現了LoadBalance接口,在覆蓋了 select 方法後,其又增長了 calculateWarmupWeight 和 getWeight 權重相關的兩個方法,由於這些方法都跟具體的負載均衡策略類有關,故在父類實現了。值得注意的是AbstractLoadBalance抽象類的 select 方法中裏留了個給子類覆蓋的 doSelect 方法,具體的負載均衡策略將在doSelect中實現。
    分析開源項目源碼,咱們該如何入手分析?(授人以漁)

  3. 閱讀源碼前首先要找到啓動類。閱讀分析源碼時要先從啓動類開始,所以找到框架啓動的入口很重要。

  4. 閱讀源碼時要分清主幹和枝節代碼。找到啓動入口後,而後就能夠順着啓動入口一步一步調試來閱讀源碼了。不過在初次調試源碼時值得注意的是必定要分清主次代碼,即要先閱讀主幹代碼,其餘枝枝節節的代碼沒明白的能夠放一邊。切忌一開始就深刻細節而後出不來了,這樣就會形成只見冰山一角而看不到全貌的感受。
  5. 閱讀源碼前要分清主次模塊。即閱讀分析源碼不能漫無目的,全盤通讀,咱們要從咱們平時有用到的模塊開始分析。每一個人的時間都很寶貴,咱們要把時間花在刀刃上。好比SpringBoot增長的新特性中有自動配置,而自動配置特性又很是重要,所以能夠挑選自動配置來進行源碼分析。
  6. 要充分利用源碼項目的測試類。以前也說過,一個框架之因此能流行,一定是通過大量測試的。所以若是咱們像具體瞭解某個類和某個方法,咱們能夠充分利用這些測試類來輔助咱們源碼分析。
  7. 要學會一些調試技巧。這一點也很重要,好比在調試過程當中如何查看調用關係等等,這裏很少說,如何高效學習和閱讀源碼這篇文章中分享了大量調試的幹活,小夥伴們能夠瞅瞅。此外,還要學會有技巧的搜索源碼,說到這裏,下面舉個栗子。

    舉個Spring事件監聽的栗子。好比咱們如今要知道哪一個監聽器監聽了ContextRefreshedEvent事件,此時咱們能夠經過idea全局搜索"(ContextRefreshedEvent"關鍵字,獲得如下截圖:從下圖能夠看到spring-webmvc模塊的FrameworkServlet,spring-context模塊的ScheduledAnnotationBeanPostProcessor,和spring-jms模塊的JmsListenerEndpointRegistry等類訂閱了ContextRefreshedEvent事件,那麼在容器刷新的時候這幾個類將會監聽到ContextRefreshedEvent事件,執行一些初始化邏輯。
    分析開源項目源碼,咱們該如何入手分析?(授人以漁)

  8. 確定還有大量的閱讀源碼技巧,但願本文能起到拋磚引玉的做用,期待小夥伴們能夠留言分享下,讓筆者也收益一下。

4 學源碼,談實踐,論堅持

最後,咱們學習源碼不是爲了學習而學習,最理想的效果咱們要學以至用。好比把從源碼中學習到的設計模式,接口設計方法,面向對象原則和相關算法等等均可以應用到咱們手頭的項目中,這纔是咱們學習源碼的最終目的,也是源碼學習的最理想的效果。可能這裏有些小夥伴會說,我平時參與的項目都是業務類的項目,而不是開發基礎框架,開發中間件,CRUD比較多,可能學習基礎框架的源碼對咱們用處不多。其實不是的,只要你有參與項目,學習源碼咱們學習的是思想,咱們就能夠把源碼框架設計中的思想應用到咱們的項目中。

最後的最後,咱們來談談堅持,這是最難能難得的。不少大道理咱們都懂,好比要堅持運動,堅持學習,堅持...,但是就是沒能堅持下來,包括我本身,嘿嘿。堅持這東西太南了,不過仍是應該給本身立個flag吧,把本身有用到的框架好比SpringBoot,Spring,Mybatis,Dubbo,SpringCloud等框架源碼都閱讀分析一遍,加油,小夥伴們共勉!

歡迎小夥伴們在評論區補充源碼閱讀技巧哦,讓筆者GET多點技能,嘿嘿。

原創不易,幫忙點個讚唄。

參考:

http://dubbo.apache.org/zh-cn/docs/dev/design.html

--------------------------------我是分隔線-----------------------------------

你們好,我是愛編碼的碼農,能夠說是一枚源碼愛好者。上週開始寫源碼分析文章,跟你們一塊兒分享本身的學習心得體會,歡迎關注我,一塊兒學習交流。
分析開源項目源碼,咱們該如何入手分析?(授人以漁)

相關文章
相關標籤/搜索