嘗試總結一下本人在看Spring,SpringMVC,Tomcat,Mybatis,Druid,Log4j2等源碼過程中的一些基本核心理念。知曉它們能加速你對源碼的理解。
1. 攔截性接口和事件通知
- 在重要的過程上設置攔截接口
- 重要的狀態(tài)的變更發(fā)送事件并留出監(jiān)聽接口
梁飛大神在發(fā)表于2010/7/5的博客一些設計上的基本常識 里完整詳盡地闡述了這兩個觀點(雖然2010年這篇博客就發(fā)表了,但本人直到2016年才看到這篇博客,真是相見恨晚)。這也是當時本人入行四年來極其少有的看到有人愿意如此透徹明了地講述一些根本性的理念,一點都不藏著掖著(上一次能給予本人以類似重塑三觀的觀點的是在SICP一書中)。 強烈建議各位去拜讀下這篇大作。雖然時隔快八年了,但其中闡述的“道”是歷久彌新的;在現(xiàn)在層出不窮的”新“框架里新瓶裝著這些老酒。
在閱讀源碼中,你會發(fā)現(xiàn)這兩個原則或原模原樣,或多穿件衣服一而再再而三地出現(xiàn)在你面前。
其它的諸如“平等對待第三方”,“微核+擴展”等我就不越皰代俎了。總而言之,這篇文章能直接帶你進入快車道。
2. 帶著問題去看
老生常談;但是我還是得強調(diào)一下。因為讀源碼不是我們的目的。拿Spring舉例,我在閱讀完Spring的核心實現(xiàn)之后, 就很少主動去看Spring相關的源代碼了,只有在碰到相關問題時,才會刻意去讀下相關的實現(xiàn)。
絕對不要漫無目的地去閱讀源碼。關于這一點就不展開了。
3. 忽略細節(jié)
本人一再強調(diào)知道自己不該自己什么同等重要。要學會容忍混沌,這是一種普世的哲學。
軟件由無數(shù)的抽象層疊加而成,不論你當前處在哪一層,往下看你都將看到黑盒。所以知道自己該在哪里停下顯得尤其重要,甚至相比較知道自己該知道什么而言更重要。
4. 考慮從低版本入手
可以故意讀一些低版本的來降低難度。當然前提是Spring這種平滑過渡的。那種暴力升級的框架還是老實跟著最新版本跑吧。
5. 學會看堆棧
這里就不廢話了,直接上圖,這是本人最近在寫SpringMVC源碼相關博客時的截圖,通過跟蹤相應的棧幀,我們可以快速地定位到我們所關心問題的可能出處。

6. 畫時序圖
2017/12/18 補充
把非常重要的一個方法給忘記了!本人看的第一個源碼就是Spring。而在看Spring源碼時本人連Spring的Hello World都寫不出來,而是直接抄起一本《Spring源碼深度解析》就開干了。
剛開始為了“節(jié)省時間”,直接一頁頁地翻,到100多頁時就徹底跟不上了。無奈之下,從頭開始,跟著作者的步伐走,學著去畫時序圖。
兩年后的現(xiàn)在,如果讓我重新選擇的話,我會第一時間打開PowerDesigner新建一個時序圖的畫布。
7. 關注命名
2018/4/26 補充
關于代碼編寫規(guī)范的書籍和文章有很多,它們中彼此之間的有些觀點不盡相同,極端點的時候甚至向左。而對于命名方面,這些書籍或文章卻都無一例外地將其擺在極其重要的地位。
一個優(yōu)秀的,經(jīng)過時間考驗的框架,其命名必然是被反復檢驗過的(所以個人認為,閱讀源碼除了理解它們蘊含的理念外,它們的命名也是非常值得學習的,鄙人就專門有一份筆記記錄著從各個源碼收集來的命名),是非常值得我們投入精力去關注的。例如上面第三條里的“忽略細節(jié)”,當我們忽略細節(jié)之后,必須得有些事物來協(xié)助我們,幫助我們理解這堆代碼是在做什么。而命名此時正是我們的得力助手,好的命名能分擔絕大多數(shù)的注釋,Bob大叔甚至認為代碼里的注釋應該盡最大可能用命名代替。他提出“不要雙語種編程”——英語也是一種語言。當時閱讀完《Clean Code》,鄙人整整半年沒寫過注釋。
說了這么多,其實就是為了強調(diào),利用好源碼里的命名,可以讓你對于源碼的理解將更上一個臺階。
8. 善用grep命令
2018/12/01 補充
有時候即使使用IDE來進行源碼閱讀,有些類的引用情況或者Constant字符串(例如一些框架打印出來的日志,我們嘗試進行反向追蹤時)的引用我們也未必能百分之百地進行定位,我們一般只能大致確定其所在的package, 甚至只能確定到jar,這會讓我們感到很被動,此時如果能借助Linux命令行工具的話,這些問題就能引刃而解了。
# 在spring-rabbit源碼路徑下執(zhí)行命令,我們就能準確定位Rabbit關閉Channel的邏輯和時機了:
grep -irn --color 'Closing cached Channel' org --include *.java
9. 掌握一些IDE調(diào)試技巧
2019/10/08 補充
參見博客: 【效率】- Eclipse調(diào)試技巧
10. 留意程序運行時候的輸出日志
2020/05/31 補充
程序運行時候的輸出日志被譽為發(fā)生線上故障的救命法寶。不論在調(diào)試源碼還是理解既有項目結構時候,通讀程序完整的輸出日志都有助于你從一個全局的視野快速把控程序的一些關鍵要素。畢竟日志輸出也是程序員一行行代碼敲出來的,作者沒有必要給自己增加非必要工作量。
11. 善用chatgpt
2023/04/07 補充
作為人類迄今為止所有知識的集合體,能夠解答萬物的存在,chatgpt的表現(xiàn)驚艷了全世界。作為排頭兵的程序員,沒有道理不用好這把快刀。
12. 選擇一款好的IDE (強烈推薦IDEA)
2023/07/02 補充
自入行Java研發(fā)以來,我一直都是將Eclipse作為自己的主力IDE,并且在其中投入了不少精力來掌握其技巧,再加上”年紀大了容易念舊,不愿接受新鮮事物“,這個習慣一直保持了現(xiàn)在。
但是,這里我必須承認,IDEA在閱讀源碼時的優(yōu)秀表現(xiàn),作為一款商業(yè)級IDE,它確實在用戶體驗方面要做得好很多。舉幾個我實際遇到的例子:
-
針對配置項的智能提示。這一功能可以大大降低我們猜測和設置第三方框架配置項時的難度,增加用戶學習和理解相關配置項的積極性。
image.png -
查找配置項實際定義,以及生效的位置。關于這一點我在eclipse中嘗試是沒有成功的。
image.png Maven依賴關系分析。 針對這一點eclipse中采用的是樹形列表結構,而人類作為視覺動物,IDEA的圖表效果展示更加吸引人。
等等。
而且,以上功能都是開箱可用的,對于新手而言,你應該將精力盡量放在主要矛盾上,而非所謂"牛逼的程序員都是用記事本做開發(fā)的"。
網(wǎng)上對于IDEA一邊倒地推薦是有其道理的。哪怕你因為種種原因選擇了Eclipse,那么至少在閱讀源碼或者遇到問題的時候,想起來在IDEA中試試。

