搶佔先機
VMware 提供培訓和認證,助力您加速發展。
瞭解更多瞭解 Spring Native 實驗性專案的人都知道,Spring 團隊自 2019 年以來一直在為 Spring 應用提供原生映象支援。繼 2021 年 3 月 釋出首個 Beta 版 後,我們於 2021 年 12 月對 Spring Native 專案進行了 重大修訂。
我們還在去年 SpringOne 大會上宣佈,我們打算在 2022 年將這項工作正式納入 Spring Framework 6.0。繼第三個里程碑版本釋出後,這篇博文將向您介紹已經包含的內容以及後續的計劃。
預先處理應用上下文為最佳化打開了許多大門。根據具體上下文,我們可以減少隨應用釋出的底層設施數量,預先計算您在元件上宣告的某些特性以加快啟動時間,並識別在受限環境中可能出現問題的事項併為其提供替代方案。
Spring Framework 6.0.0-M3
釋出了基於 Spring Native 的第一批此類特性,並經過了廣泛審查並整合到核心容器中。它不是以附加模組的形式作為新特性,而是深度整合到現有核心模組中。目前包含:
當典型的 Spring 應用執行時,應用上下文會呼叫許多後處理器來準備 Bean 工廠:配置類解析、類路徑掃描以及其他最終可能觸發自動配置解析的處理器。一旦這些處理器執行完畢,在大多數情況下,它們在執行時就不再需要了。
在環境(類路徑等)定義清晰的情況下,這可以在構建時完全完成,以便只有與當前環境相關的 Bean 定義被貢獻到 Bean 工廠。在構建時執行的後處理器會被丟棄,並由它們貢獻的程式碼替代。
有許多方法可以“預先”貢獻程式碼,從註解處理到位元組碼生成。我們選擇讓新引擎生成 Java 原始碼,並在構建期間將其貢獻給應用。我們相信這在開發者體驗和最佳化機會之間取得了恰當的平衡。
這不僅應以熟悉和透明的方式支援原生用例,我們還相信這將在未來為普通的 JVM 應用帶來好處。例如,AOT 引擎完全獨立於原生,因此您可以在 JVM 上驗證應用的最佳化版本是否正常工作。
與 JVM 不同,執行原生映象在某些場景下需要額外的配置。例如,如果您的程式碼透過反射呼叫方法,您需要進行說明,以便必要的底層設施被包含在原生映象中。或者,如果您需要讀取類的元資料(核心容器在啟動時經常這樣做),您需要將類的位元組碼包含進來,這可能導致映象大小顯著增加。
AOT 引擎將自動推斷啟動核心容器所需的所有提示。未來,我們希望這些提示會減少,這得益於 GraalVM 本身的改進,或者最佳化方面的變化使得它們不再需要。
程式碼生成需要良好的測試支援。很容易貢獻無法編譯的程式碼,或者能編譯但無法達到預期結果的程式碼。我們一直在開發新的測試工具來幫助解決這個問題,您可以在當前私有的 spring-core-test
模組中找到它們。
簡而言之,這個基礎設施允許我們編譯程式碼(透過一個抽象層,使得我們可以在記憶體中提供原始碼),並執行斷言,其中生成的程式碼可以輕鬆檢索到。
假設我們為一些 Java 類生成了程式碼,並且入口點是 MyObject
TestCompiler.forSystem().withSources(sourceFiles)
.compile(compiled -> {
MyObject instance = compiled.getInstance(MyObject.class);
// invoking + assertions
});
在我們的案例中,AOT 引擎生成一個實現 ApplicationContextInitializer
介面的入口點。這樣的基礎設施使我們能夠執行以下操作:
TestCompiler
編譯我們生成的原始碼上面描述的關於生成的程式碼同樣適用於執行時提示。我們正在開發額外的測試工具,以驗證您貢獻的提示與執行時行為是否匹配。但這尚未包含在此里程碑版本中,請關注 #27981 獲取更多詳細資訊。
在下一個里程碑版本中,我們將繼續基於 Spring Native 的經驗構建核心基礎設施。過去在 Spring Native 中的針對特定 Spring 專案的定製將遷移到相應的專案本身,或者透過適應引擎開箱即用的支援而變得不再需要。
Spring Framework 6.0 只是第一步:我們打算在此基礎上繼續發展多年,這也將對 JVM 使用者產生積極影響。敬請期待!