Spring Framework 6.0.0-M3 中的初始 AOT 支援

工程 | Stéphane Nicoll | 2022 年 3 月 22 日 | ...

如果您熟悉 Spring Native 實驗性專案,您會知道 Spring 團隊自 2019 年以來一直在為 Spring 應用程式開發原生映像檔支援。繼 2021 年 3 月的 第一個 beta 版之後,我們在 2021 年 12 月推出了 對 Spring Native 進行的大規模修訂

我們也在去年 SpringOne 大會上宣布,我們計劃在 2022 年期間將此工作提升到 Spring Framework 6.0。在發布第三個里程碑之後,這篇部落格文章將引導您了解已包含的內容以及接下來的內容。

提前編譯處理 (Ahead-Of-Time Processing)

提前處理應用程式上下文為最佳化開啟了許多扇門。根據上下文,我們可以減少運送的基礎架構量、預先計算您在元件上聲明的某些功能,從而縮短啟動時間,並識別受限環境中可能存在問題的事項,並為其提供替代方案。

Spring Framework 6.0.0-M3 根據 Spring Native 提供第一批這些功能,但具有擴展的審查和整合到核心容器中。它沒有以附加模組的形式將其作為一項新功能,而是深入整合到現有模組的核心中。目前它包含:

  • 一個引擎,可針對給定的類別路徑處理 ApplicationContext,並提供程式碼,以提供其最佳化版本。
  • 一個新的 API,用於貢獻運行時提示:整合者通常會在他們需要在自己的元件中使用反射,或者他們需要存取類別路徑上的某些資源時使用它。這些提示與 GraalVM 相容,我們提供基礎架構來產生適當的配置檔案。

在建置時最佳化應用程式

當典型的 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 介面的進入點。這種基礎架構讓我們可以執行以下操作:

  • 配置應用程式上下文以執行特定功能
  • 在上下文中調用 AOT 引擎
  • 使用 TestCompiler 編譯我們生成的原始碼
  • 建立一個新的應用程式上下文並應用生成的程式碼,以查看該功能的行為是否如預期

上面描述的關於生成程式碼的內容同樣適用於提示。我們正在開發額外的測試實用程式,以驗證您貢獻的提示是否與運行時行為相符。這沒有進入這個里程碑,請訂閱 #27981 以了解更多詳細資訊

下一步是什麼?

我們將在下一個里程碑中根據 Spring Native 的經驗繼續建立核心基礎架構。曾經在 Spring Native 中的特定 Spring 專案的自定義設定將遷移到適當的專案,或者透過適應引擎提供的開箱即用功能而變得無關緊要。

Spring Framework 6.0 僅僅是第一站:我們計劃在未來的幾年內以此為基礎,這也將對 JVM 用戶產生積極的影響。請繼續關注!

取得 Spring 電子報

隨時關注 Spring 電子報

訂閱

搶先一步

VMware 提供培訓和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部