Spring源碼閱讀環境搭建(以及執行單元測試後的錯誤解決)

前期運行環境與工具準備

  • JDK版本:1.8.0_162 (版本1.8就行,我的是1.8最新版,高於1.8的沒試過)
  • 下載地址:https://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html
  • GRADLE版本:4.10.3(也可用idea自帶的gradle導入就行,如果自己安裝需要配置相關環境)
  • 注意:這裏會有一個問題,就是如果我們創建的項目和Gradle版本衝突了怎麼辦,也就是說Spring需要的版本和我們下載的版本不一致時怎麼辦?

  • 解決:我們先不配置Gradle,在本地打開 Spring 目錄,在當前目錄打開 cmd,輸入命令:

  • gradlew :spring-oxm:compileTestJava

  • 出現BUILD SUCCESS字樣時說明構建成功,如下圖所示
  • bulid
  • 在 Spring-frameword-5.1x/.gradle 目錄中可以看到 4.10.3,那麼下載4.10.3版本即可。
  • 另外,如果電腦本身就有Gradle那麼直接進行下一個板塊的步驟,導入IDEA,在IDEA中編譯 compileTestJava 即可,可以以看到相應的 Gradle 版本
  • 當然下載好之後要重新配置 Gradle 的環境變量,我就是因爲電腦本身就有 Gradle,弄了很多次都不行,最後重新下載對應版本的 Gradle 版本。
  • 配置教程:https://www.cnblogs.com/linkstar/p/7899191.html
  • 這裏得再加一步,爲了編譯過程更快,我們爲安裝好的Gradle配置國內鏡像
  • 進入 Gradle 安裝目錄,在 init.d 目錄下新建一個 init.gradle 文件,並添加以下內容:
  • allprojects{
        repositories {
            def REPOSITORY_URL = 'http://maven.aliyun.com/nexus/content/groups/public/'
            all { ArtifactRepository repo ->
                def url = repo.url.toString()
                if ((repo instanceof MavenArtifactRepository) && (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com'))) {
                    project.logger.lifecycle 'Repository ${repo.url} replaced by $REPOSITORY_URL .'
                    remove repo
                }
            }
            maven {
                url REPOSITORY_URL
            }
        }
    }
  • Spring 源碼版本:v5.1.X.RELEASE (目前最新版爲:5.2.1.RELEASE,下載最好用VPN,不然很慢)
  • 下載地址:https://github.com/spring-projects/spring-framework
  • IntelliJ IDEA版本:IntelliJ IDEA 2018.2.5(2017也可以,我的是2018)
  • 下載地址:https://www.jetbrains.com/idea/download/
  • 系統:WINDOWS 10

下載源碼

  • 我這裏選擇的是5.1.x版本的Spring,然後點擊Clone or download,如果會Git可以使用Git命令的方式,不會的話選擇下載ZIP壓縮包,下載好之後需要解壓
  • 解壓好之後,我們爲 Spring 添加阿里雲鏡像
  • 在編譯過程中,Spring會去自動下載一些依賴的包,默認使用的是官方的鏡像,下載比較慢,所以我們提前添加好國內鏡像,將下面這行代碼粘貼到build.gradle文件中的repositories節點下即可 
  • //添加阿里雲鏡像
    maven { url "http://maven.aliyun.com/nexus/content/groups/public" }

導入IDEA

  • 點擊File->New->Project form Existing Sources...打開項目
  • 選擇剛剛解壓的spring項目工程
  • 選擇 Gradle
  • 選擇自己配置的Gradle環境
  • 調整內存:-XX:MaxPermSize=2048m -Xmx2048m -XX:MaxHeapSize=2048m
  • 點擊Finish
  • 注意:在點擊finish前,最好是能夠開啓VPN,構建過程會要下載大量的依賴包跟插件,這裏下載要很長時間我當時沒有及時,做好去喫個飯,回來就差不多了,喫得快的可以再喫一頓,反正很慢。

  • 下載過程:

  • 項目導入到IDEA成功,如下圖所示:

開始準備編譯

  • 修改docs.gradle文件
    • 打開docs.gradle文件準備修改
  • 註釋掉dokka和asciidoctor兩個配置項
    • 因爲在構建過程中執行這兩個任務時會導致構建失敗,這兩個任務主要是用來生成文檔使用,對主流程並沒有任何影響,可以直接忽略,當然如果大家本地沒有這個問題,也可以不註釋。
  • 替換docs.gradle文件中的task schemaZip配
    • gradle的構建腳本,只針對Linux系統做了適配,需要把task schemaZip替換成下面代碼,因爲原有代碼的路徑符號" / "是針對Linux的,windows使用會有問題,在windows環境需要替換成" \\ "否則會出現異常。
    • 參考如下代碼,註釋部分是原有的代碼:
    • //這部分被替換了,所以需要被替換掉
      //task schemaZip(type: Zip) {
      //	group = "Distribution"
      //	baseName = "spring-framework"
      //	classifier = "schema"
      //	description = "Builds -${classifier} archive containing all " +
      //			"XSDs for deployment at https://springframework.org/schema."
      //	duplicatesStrategy 'exclude'
      //	moduleProjects.each { subproject ->
      //		def Properties schemas = new Properties();
      //
      //		subproject.sourceSets.main.resources.find {
      //			(it.path.endsWith("META-INF/spring.schemas") || it.path.endsWith("META-INF\\spring.schemas"))
      //		}?.withInputStream { schemas.load(it) }
      //
      //		for (def key : schemas.keySet()) {
      //			def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
      //			assert shortName != key
      //			File xsdFile = subproject.sourceSets.main.resources.find {
      //				(it.path.endsWith(schemas.get(key)) || it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')))
      //			}
      //			assert xsdFile != null
      //			into (shortName) {
      //				from xsdFile.path
      //			}
      //		}
      //	}
      //}
      
      //替換成如下代碼即可
      task schemaZip(type: Zip) { 
          group = "Distribution" 
          baseName = "spring-framework" 
          classifier = "schema" 
          description = "Builds -${classifier} archive containing all " + 
                  "XSDs for deployment at http://springframework.org/schema." 
          duplicatesStrategy 'exclude' 
          moduleProjects.each { subproject -> 
              def Properties schemas = new Properties(); 
              subproject.sourceSets.main.resources.find { 
                  it.path.endsWith("META-INF\\spring.schemas") 
              }?.withInputStream { schemas.load(it) } 
      
              for (def key : schemas.keySet()) { 
                  def shortName = key.replaceAll(/http.*schema.(.*).spring-.*/, '$1')
                  assert shortName != key 
                  File xsdFile = subproject.sourceSets.main.resources.find { 
                      it.path.endsWith(schemas.get(key).replaceAll('\\/','\\\\')) 
                  } 
                  assert xsdFile != null 
                  into (shortName) { 
                      from xsdFile.path 
                  } 
              } 
          } 
      }
      
  • 到現在編譯前的準備工作纔算完成

根據import-into-idea.md文檔步驟去構建

  • 打開spring工程的import-into-idea.md文件
    • import-into-idea.md裏面詳細的描述了編譯步驟,根據import-into-idea.md文檔裏面介紹,我們需要對spring-core和spring-oxm做預編譯
  • 預編譯
    • 在IDEA中預編譯很簡單,按下圖操作即可:
    • 注意:如果右側沒有Gradle那麼可以在View中讓它顯示
    • 出現如下圖所示,表示預編譯成功
    • 上邊的過程演示了 :spring-oxm 的預編譯,:spring-core和它同理這裏就不演示了,成功顯示如下圖即可
  • 終極編譯
    • 對整個Spring項目構建,這個時候它會自動下載依賴包,如果有異常,會在控制檯拋出並停止操作,編譯整個工程,需要20分鐘左右的時間。
    • 構建成功在控制檯可以看到下圖提示

執行單元測試

  • 即使整個項目沒有Error或者紅點,也不代表項目已經成功構建好了,我們還需要執行個單元測試試下,如果能順利執行單元測試,那證明該項目已經構建成功,這裏我用到的是DispatcherServletTests這個類,直接運行查看結果:
  • 我第一次執行的時候報錯了,錯誤如下:
  • 網上找了很多解決辦法還是沒用
  • 比如這個:
  • 結果出來的錯誤更離譜,網上根本找不到相關示例,最後實在是找不到只能重新再來一次
  • 還有這個:
  • 這個還是不行,雖然報錯沒有更離譜,但是還是會有錯誤,只是錯誤沒有改變罷了
  • 還有這個:
  • 這個還是不行,把這個類註釋掉,那麼還會有其他類報錯,最後根本註釋不完
  • 最後我也找了很久,終於讓我找到了
  • 視頻參考:https://www.bilibili.com/video/av76404922
  • 解決辦法就是將找不到符號的那個類的子模塊的build文件刪除,再次重新build一遍即可,如果還是不行那麼把該模塊的text文件中的代碼重新運行run一遍,之後再運行測試類即可。之後如果還是顯示找不到符號,重複上述步驟即可。
  • 看完視頻我的使用視頻中的方式,之後還是會有其他的報錯,但是報的錯都是找不到符號,我還是使用同樣的方法,進行重新rebuild,之後再將text中的類重新運行run一遍即可。
  • 很明顯,上面單元測試類的所有單測執行成功。
  • 當我第二次安裝的時候又遇到了不一樣的坑
  • 在編譯 spring-aspect 的 javadoc 時我等了半個多小時還是不動,之後又重新弄了很多次,還是不行。
  • 解決:註釋掉 build.gradle 中的一些代碼:
  • //	javadoc {
    //		description = "Generates project-level javadoc for use in -javadoc jar"
    //
    //		options.encoding = "UTF-8"
    //		options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
    //		options.author = true
    //		options.header = project.name
    //		options.use = true
    //		options.links(project.ext.javadocLinks)
    //		options.addStringOption("Xdoclint:none", "-quiet")
    //
    //		// Suppress warnings due to cross-module @see and @link references.
    //		// Note that global 'api' task does display all warnings.
    //		logging.captureStandardError LogLevel.INFO
    //		logging.captureStandardOutput LogLevel.INFO  // suppress "## warnings" message
    //	}
    
    	task sourcesJar(type: Jar, dependsOn: classes) {
    		duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    		classifier = "sources"
    		from sourceSets.main.allSource
    		// Don't include or exclude anything explicitly by default. See SPR-12085.
    	}
    
    //	task javadocJar(type: Jar) {
    //		classifier = "javadoc"
    //		from javadoc
    //	}
    
    	artifacts {
    		archives sourcesJar
    //		archives javadocJar
    	}
    }
  • 然後暫停當前運行,重新 build 即可。

可能遇到的坑點回顧

  • 構建成功沒報錯,但運行單元測試有異常 ,提示類找不到
    • 方案1:嘗試點擊右邊菜單欄projects刷新項目,然後對Spring(Root)模塊先clean再build一次
    • 方案2:針對找不到類的模塊重新build一次
    • 方案3:點擊Spring(root)模塊下的Tasks->other->compileTestJava 執行一遍,針對test類編譯一次即可
  • 構建失敗,缺少依賴包
    • 方案1:對Spring(Root)模塊先clean再build一次(建議打開VPN,有可能存在某些包下載不成功導致)
    • 方案2:嘗試針對當前模塊執行buildDependents
  • 構建失敗,執行gradle task失敗
    • 方案1:可能是當前運行環境版本不支持問題,如果不重要的問題,可以註釋掉,保證構建正常
  • 構建失敗,編碼異常
    • 方案1:可以通過idea工具設置:Editor-File encodings 全部設置爲UTF-8

有興趣的同學可以關注我的個人公衆號,期待我們共同進步!!!

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