Spring5.x源碼編譯及導入IDEA全過程及踩坑記錄

1.寫在前面

Spring作爲風靡世界的優秀框架,很早就想研究研究Spring源碼了。最近親手搭建了Spring環境,從下載源碼到編譯到改動源碼測試demo跑通,有些踩坑和心得需要記錄一下,也與大家分享一下。
注:筆者在2臺不同電腦上均告成功,但是也不敢保證各位看官一定能成功,如果失敗請輕拍磚。不過相信對各位編譯Spring還是有一定幫助的,廢話不多說,Let’s Go Go Go!

2.編譯前需要準備的環境和工具。

  • 操作系統:俺是在Win10上編譯的
  • Java環境:1.8.0_151
    注意:有網友說JDK版本不能過高,比如jdk1.8_20和jdk1.8_191,因此當遇到一堆 0x000000: xxxxxxxx 之類的錯誤時,請留意你的JDK版本。
  • 源碼下載:講真,想在GitHub上下載,太難了,筆者試了若干次沒有成功。逼不得已,去碼雲上下載的。如果看官也被逼上"碼雲",請注意,在搜索框輸入:Spring-Framework,然後請選擇這個庫:

碼雲極速下載 / Spring-Framework

,然後挑選需要的源碼。筆者選擇的是:v5.0.0.RELEASE,然後通過zip方式下載的。

  • Gradle:Spring是通過Gradle構建的,因此需要下載安裝一個Gradle。很簡單,下載解壓,配置環境變量即可。
  • idea:筆者使用的2019 1.1版本

3.具體步驟

  1. 相信你已經安裝好了JDK,idea,讓我們往下。

  2. 將下載好的源碼包放到一個單獨目錄,解壓之。根目錄下留心下面幾個文件。

    • build.gradle :這是和Spring構建有關的文件,後面會有所修改。
    • import-into-idea.md :這是關於導入idea的一個說明文件。裏面有關於導入idea的信息,這是我們需要的,裏面有個命令馬上就會用到。
  3. 在 import-into-idea.md文件中,有這麼一句話

    Precompile spring-oxm with ./gradlew :spring-oxm:compileTestJava

    說得很清楚,需要預先編譯spring-oxm模塊,使用gradlew :spring-oxm:compileTestJava這個命令。好照着做。但是等等,1號坑出現,如果不想編譯後出現類似這樣的錯誤

    Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002

    那麼一定要在 管理員窗口 中執行gradlew :spring-oxm:compileTestJava命令。如下:
    在這裏插入圖片描述

  4. 執行命令後,從上面圖片中可以得到4個信息:

    • 其一:會自動下載gradle-4.1-bin.zip,筆者曾試過,就算本機安裝有一個gradle,配置好環境變量,這裏spring也會去下載一個。不知道是正常還是不正常。但是你還是應該去gradle官網下載一個gradle,因爲待會兒導入idea要用,不建議用idea自帶的。
    • 其二:注意2號坑出現,你下載安裝的gradle版本不能太高,過高的話,導入idea後,會出現各種頭疼的問題導致你心態炸裂。那麼下載什麼版本呢?其實spring已經告訴你了,去下載一個和他自動安裝的那個版本就好了。而且v5.0.0.RELEASE對應的gradle版本是gradle-4.1,其他的可不一定,以spring自己打印出來的版本爲準。
    • 其三:spring會自己去下載一些包來支撐構建,而從上面圖片來看,下載地址是https://repo.spring.io/plugins-release。一般說來速度不會很慢,但是如果速度慢怎麼辦?拿鞭子抽它,讓它加速。下面第5步,是可選步驟,如果很慢的話,可以按照第5步操作,如果不慢,就跳過。一般說來,這一步預編譯步驟,不應該超過10分鐘。
    • 其四:編譯的時候,有個進度條,和打印一些信息的東西,有時候界面會看似卡死不動,其實是在正常進行的,敲一下回車,就可以看到了,不會打斷編譯過程的,放心敲。
  5. 【可選步驟】加速編譯spring-oxm模塊。原理就是添加一個阿里雲鏡像。如果你發現下載速度很慢,Ctrl + C退出編譯,然後在spring源碼包下,打開build.gradle文件,像下圖一樣,將紅框中的部分添加到文件中。
    在這裏插入圖片描述

    注意點:

    1. 綠色框中的是文件本來就有的,不要刪掉它,因爲有些插件包,阿里雲並沒有同步完全,如果刪掉,很可能下載不下來而導致失敗。另外它的順序應該如圖一樣,排在最後。
      2.allprojects那個框,也保持如圖中的位置,不要移動到plugins上面。

    再一次執行gradlew :spring-oxm:compileTestJava命令。注意在管理員窗口執行。

  6. 稍等一會兒,不管有沒有執行第5步,你應該都可以得到一個編譯成功的結果。如下:
    在這裏插入圖片描述
    只不過進了第5步的話,應該還是會快點,在筆者的後面幾次實驗中,只用了2分半鐘。
    另外,預編譯成功後,可以打開源碼包看看,其實有些核心模塊,比如core,context,已經編譯出jar包了,但是像jdbc等模塊,是沒有的,因此可以導入idea來繼續編譯,不過應該是可以繼續在管理員窗口編譯的,有興趣的可以自行嘗試。

  7. 導入idea之前,覈實一下是否按照第4步中,安裝好了gradle,如果是,需要配置一下繼續go go go

  8. 打開idea,在WelCome頁面,點擊open,選擇編譯好的Spring源碼根目錄,自動彈出如下gradle項目嚮導,按下圖配置即可。ps:如果沒有,請覈實自己的idea是否安裝了gradle插件。
    在這裏插入圖片描述

  9. 點擊OK,idea會自動構建環境,下載包等,此時等待。如果按照上面的步驟來,此處應該是能成功的。不然很多坑就會在這裏應驗 ^ _ ^。
    在這裏插入圖片描述

  10. 等到IDEA構建好之後,出現如上圖的幾個綠條。那麼就可以打開右側Gradle面板,進行編譯了。如圖:
    在這裏插入圖片描述

    • 可以選擇點擊1號框,手動輸入命令編譯
    • 也可以雙擊2號框,直接編譯。
  11. 但是注意,3號坑出現。此坑說來話長,但是不得不說。Spring源碼有當前master分支,和歷史各個分支,還有RELEASE版本。如果你是選擇clone master分支來編譯,那麼是不會編譯生成文檔包和源碼包的。如果是歷史分支,Release版本,則會做這些事情,比如筆者目前選擇的v5.0.0.RELEASE版本。但是,在Win10系統上,編譯生成文檔包,會遇到一些非常棘手的事情,如果你嘗試這樣編譯了,會發現控制檯打印出一些???和亂碼,並且最後編譯失敗(其實也不算失敗,文檔失敗了而已)得到類似這樣的錯

    Execution failed for task ‘:asciidoctor’.

    (SystemCallError) Unknown error 123 - FindFirstFile

    這個錯是因爲Win10路徑的一些兼容問題,很難解決,如果只是爲了閱讀源碼,沒有必要在這個問題糾結。如果是正式的用途,那可以到Linux環境進行編譯。
    那麼我們的解決方式就是:跳過文檔源碼包編譯
    找到如下2個地方,註釋掉(另外看官們可以去GitHub上瞧瞧,master分支上沒有下面2個東西,所以編譯master分支時不會遇到3號坑,但編譯Release版本,則會遇到):
    在這裏插入圖片描述在這裏插入圖片描述

  12. 現在又可以雙擊build進行編譯了,不會出現剛剛一堆紅色???了,但是世界似乎仍不安靜,控制檯在打印一些白色FAILED。這是因爲編譯測試程序出了問題。這裏筆者曾經嘗試解決,但是當解決了一個模塊後,另一個模塊的測試又會出問題,時間有限,這裏只給出解決思路和1個例子。
    在測試程序失敗後,會出具一份Report,在控制檯可以看到連接,可以複製出來在瀏覽器打開,可以看到報錯信息,哪些類失敗等。
    比如這個問題:

     Execution failed for spring ':spring-webflux:test'
    

    解決辦法是:將

    compile"com.fasterxml.jackson.module:jackson-module-kotlin:2.9.0"
    

    放入spring-webflux的gradle dependencies 節點中。

    由於筆者只是研究一下Spring源碼,於是選擇跳過測試程序,有興趣的可繼續自行解決。進行下一步

  13. 跳過測試。點擊第10步1號框,手動輸入下面命令來跳過測試執行編譯。

    build -x test
    

    這樣只編譯源碼,就很快了,快的幾十秒,慢點幾分鐘就打完收工。
    在這裏插入圖片描述

  14. 編譯完畢,下一步就是新建一個模塊來測試一下啦。

    1. new -> module -> gradle -> next -> 輸入artifactID -> 確定
    2. 向自動生成的gradle文件的dependencies中添加一行:compile(project(’:spring-context’))
    3. 新建測試類
     public class HelloSpring {
        public void say(){
    	System.out.println("hello spring");
        }
    }
    
    public class TestClient {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.refresh();
            context.register(HelloSpring.class);
            HelloSpring helloSpring = (HelloSpring)context.getBean("helloSpring");
            helloSpring.say();
        }
    }
    
  15. 點擊運行。nice,4號坑出現。應該會得到下面一個錯誤

        Error:(26, 38) java: 找不到符號
      符號:   類 InstrumentationSavingAgent
      位置: 程序包 org.springframework.instrument 
    

    解決辦法是:將下圖本來爲optional的,改爲compile
    在這裏插入圖片描述

  16. 再次點擊運行,運行成功。v5.0.0.RELEASE版本編譯到此結束。
    在這裏插入圖片描述

  17. 都運行成功了,爲什麼還有下一點呢?因爲還有5號坑,但是此坑在編譯v5.0.0.RELEASE版本的時候,並沒有出現。而出現在了編譯master分支上,目前master版本是5.2.2,當運行測試程序的時候,很可能得到這個錯誤:

    Error:(347, 51) java: 找不到符號
      符號:   變量 CoroutinesUtils
      位置: 類 org.springframework.core.ReactiveAdapterRegistry.CoroutinesRegistrar
    

    這是因爲有個包,spring沒有幫你打進去,需要自己添加,如下操作:

    1. 找到Spring-core模塊,右鍵新建一個lib文件夾
    2. 按照如下圖所示,將包複製過去
      在這裏插入圖片描述
    3. 打開spring-core.gradle文件,將compile fileTree(dir:'lib',includes:['*jar']) 添加到dependencies,如下圖
      在這裏插入圖片描述
      然後idea觸發自動編譯。編譯好後,運行測試程序,問題解決。

4.總結

以上都是

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章