前言

spring原始碼本地編譯,按網上的部落格參考資料的操作步驟,總是會出現各種莫名其妙的錯誤。根據錯誤資訊找解決方案,但在自己的環境下又總是編譯不過去。結合參加培訓學習Jack老師提供的方法,自己多種方式嘗試,最終編譯成功了。

為了驗證自己的方式是否有失誤的地方,全部過程我自己走了大概5遍,詳細記錄下每個步驟。如果按1天8小時計的話,為了這個原始碼編譯至少花了3~4天時間。我覺得是值得的,為後面的原始碼閱讀掃除一個攔路虎。

僅以此篇記錄踩到的坑,為同樣想讀原始碼的同學可以在編譯這一步少花一些時間,也可以後面原始碼閱讀增加自信心。同時感謝在網上留下部落格的同學,給予我相當多的幫助,這也是我想寫這篇文章的原因。

參考部落格:

https://www.it610.com/article/1295306604677242880.htm
https://www.cnblogs.com/haoxianrui/p/12825586.html
https://www.cnblogs.com/jhj117/p/5455081.html

1.資源及環境說明:

idea 2019.3.3

gradle-5.6.4版本(對原始碼裡面的版本,版本需要一致,否則編譯過程會出現各種異常)

jdk1.8 or 以上版本

spring-5.2.8.RELEASE

系統:win7 or 以上

2.下載原始碼

選擇gitee下載速度快,官網速度非常慢,耗時約60s
git clone --branch v5.2.8.RELEASE https://gitee.com/Z201/spring-framework.git

2.1.檢視原始碼gradle版本號

檢視檔案路徑:/gradle/wrapper/gradle-wrapper.properties

對應的gradle版本:gradle-5.6.4-bin.zip

3.gradle下載&配置環境變數

3.1.gradle下載

# gradle 下載地址
https://services.gradle.org/distributions/
選擇版本: gradle-5.6.4-bin.zip
下載到本機,並解壓到指定路徑

3.2.配置環境變數

配置環境變數
變數名:GRADLE_HOME
變數值:A:\java_about\gradle-5.6.4
在Path加上 ;%GRADLE_HOME%\bin

3.3.驗證gradle

4.原始碼配置相關修改

4.1.gradle-wrapper.properties配置修改

目錄:spring-framework/gradle/wrapper
修改 distributionUrl=file:///A:/java_about/gradle-5.6.4-bin.zip #(本機的所在路徑)

4.2.確認kotlin版本號

先檢視idea的kotlin版本,檢視路徑:File->Setting->Plugins,搜尋kotlin,如果還沒安裝過先安裝一下。

我的版本號是1.3.61

4.3.build.gradle配置

目標檔案:build.gradle 在根目錄下

4.3.1.註釋gradle企業約束

因為該plugins不註釋,會發生很多不可預期的錯誤,

搜尋關鍵字:io.spring.gradle-enterprise-conventions

註釋如下:

//	id 'io.spring.gradle-enterprise-conventions' version '0.0.2'

4.3.2.確認kotlin版本號是否一致

如果不一致,修改成跟idea的kotlin的版本號一樣,我的版本號為1.3.61,而Spring-5.2.8.RELEASE對應kotlin的版本號是1.3.72,所以需要修改。需要修改的地方有2處

搜尋關鍵字:kotlin.jvm    ,    kotlin-bom

4.3.3.新增上阿里映象

為倉庫新增上阿里映象,目的是加快資源下載,編譯速度加快。行號約279,在dependencyManagement下的repositories 新增:

maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter'}

4.4.settings.gradle配置

為外掛倉庫新增上阿里映象,行號約2,在pluginManagement下的repositories 新增:

maven { url "https://maven.aliyun.com/repository/public" }

4.5.解決gradle build慢問題

目標檔案:gradle.properties

1.增加記憶體分配 -- 這個按本機的記憶體去分配,我的是16G
org.gradle.jvmargs=-Xmx2048M 2.按需配置
org.gradle.configureondemand=true 3.開啟守護程序
org.gradle.daemon=true

5.idea匯入原始碼

依次點選File->New->Project from Existing Sources,選擇原始碼包路徑下的build.gradle檔案完成原始碼匯入

5.1.idea配置gradle

可以預先開啟idea配置,也可在匯入過程中去配置(匯入後會出現一個進度條,選擇backgroud後臺執行)

操作路徑:File->Setting->Build,Execution,Deployment->Build Tools->Gradle

5.2.匯入等待&configure成功

以上設定完成後,就是等待過程了,具體多長時間看網速,我的匯入編譯完成耗時約11m 57s,一次性成功。

編譯日誌內容如下:

Starting Gradle Daemon...
Gradle Daemon started in 4 s 477 ms
> Task :buildSrc:compileJava
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors
> Task :buildSrc:processResources
> Task :buildSrc:classes
> Task :buildSrc:jar
> Task :buildSrc:assemble
> Task :buildSrc:pluginUnderTestMetadata
> Task :buildSrc:compileTestJava NO-SOURCE
> Task :buildSrc:compileTestGroovy NO-SOURCE
> Task :buildSrc:processTestResources NO-SOURCE
> Task :buildSrc:testClasses UP-TO-DATE
> Task :buildSrc:test NO-SOURCE
> Task :buildSrc:validateTaskProperties
> Task :buildSrc:check
> Task :buildSrc:build CONFIGURE SUCCESSFUL in 11m 57s

5.3.預編譯

在idea底部選單欄,切到Terminal選單,輸入spring-oxm的預編譯命令:

 gradlew :spring-oxm:compileTestJava

預編譯成功,耗時約 29s:

6.測試

6.1.前置說明

在spring-context新增測試類,測試驗證是否能編譯通過,拿到例項的物件。

6.2.新增測試實體類

為了快速定位到,先新增測試的package: com.elephant.bean , 建立Student實體類

package com.elephant.bean;

import org.springframework.stereotype.Service;

@Service
public class Student { private String username = "elephant"; private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
}

6.3.測試配置檔案

spring-test.xml ,目錄在test/resources,內容如下:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<context:component-scan base-package="com.elephant"/>
</beans>

6.4.新增測試類

為了快速定位到,先新增測試的package: com.elephant.test , 建立MyTest類

package com.elephant.test;

import com.elephant.bean.Student;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test1() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-test.xml");
Student student = (Student)applicationContext.getBean("student");
System.out.println(student.getUsername());
System.out.println("我獲取使用者名稱了:"+student.getUsername());
}
}

6.5.執行測試

在類MyTest 方法 test1() 右擊Run,然後等待執行結果。

6.6.執行結果

耗時約 1m 36s

預期結果:成功打印出student的userName , 結果符合預期,成功!

我獲取使用者名稱了:elephant
BUILD SUCCESSFUL in 1m 36s
50 actionable tasks: 26 executed, 7 from cache, 17 up-to-date
The remote build cache was disabled during the build due to errors.
18:34:24: Tasks execution finished ':spring-context:cleanTest :spring-context:test --tests "com.elephant.test.MyTest.test1"'.