預先最佳化

本章介紹了 Spring Data 的提前(AOT)最佳化,這些最佳化基於 Spring 的提前最佳化

最佳實踐

註解您的領域型別

在應用程式啟動期間,Spring 會掃描類路徑以查詢領域類,用於實體的早期處理。透過使用 Spring Data Store 特定的 @Table@Document@Entity 註解標記您的領域型別,您可以幫助進行初始實體掃描,並確保這些型別在 ManagedTypes 中註冊以用於執行時提示。在原生映象安排中無法進行類路徑掃描,因此 Spring 必須使用 ManagedTypes 來獲取初始實體集。

提前程式碼生成

提前程式碼生成不僅限於與 GraalVM Native Image 一起使用,在常規部署中也提供優勢,並有助於最佳化 JVM 上的啟動效能。

透過 AOT 最佳化,一些決策(例如資料庫方言)將在構建時凍結,並按原樣包含在應用程式設定中。

如果啟用了提前編譯,Spring Data 可以(根據實際使用的模組)在構建的 AOT 階段貢獻多個元件。

  • 生成的型別/屬性訪問器的位元組碼

  • 定義的 Repository 介面的原始碼

  • JSON 格式的 Repository 元資料

以上各項預設啟用。但是,使用者可以透過以下選項微調配置。

spring.aot.data.accessors.enabled

布林標誌,用於控制生成的型別/屬性訪問器位元組碼的貢獻

spring.aot.data.accessors.include

以逗號分隔的 FQCN 列表,用於貢獻生成的型別/屬性訪問器位元組碼。Ant 風格的包含模式匹配包名(例如 example.springdata.**)或型別名包含。如果某個型別同時匹配包含和排除,則包含優先,該型別被視為已包含。

spring.aot.data.accessors.exclude

以逗號分隔的 FQCN 列表,用於跳過貢獻生成的型別/屬性訪問器位元組碼。Ant 風格的排除模式匹配包名(例如 example.springdata.**)或型別名排除。如果某個型別同時匹配包含和排除,則包含優先,該型別被視為已包含。

spring.aot.repositories.enabled

布林標誌,用於控制 Repository 介面原始碼的貢獻

spring.aot.[module-name].repositories.enabled

布林標誌,用於控制特定模組(例如 cassandrajdbcjpamongodb)的 Repository 介面原始碼的貢獻

spring.aot.repositories.metadata.enabled

布林標誌,用於控制包含查詢方法和實際查詢字串的 JSON 儲存庫元資料的貢獻。需要啟用 spring.aot.repositories.enabled

提前(AOT)Repository

提前儲存庫僅適用於某些模組的命令式(非響應式)儲存庫介面。識別符合條件的查詢方法的標準因實現模組而異。

AOT Repository 是 AOT 處理的擴充套件,透過預生成符合條件的查詢方法實現。查詢方法對開發人員來說是不透明的,因為它隱藏了在查詢方法呼叫中執行的底層查詢。AOT Repository 基於在構建時已知的派生、註解和命名查詢來貢獻查詢方法實現。這種最佳化將查詢方法處理從執行時移至構建時,這可以顯著提高效能,因為查詢方法無需在每次應用程式啟動時進行反射分析。

生成的 AOT 儲存庫片段遵循 <Repository FQCN>Impl__AotRepository 的命名方案,並放置在與儲存庫介面相同的包中。

請將 AOT Repository 類視為內部最佳化。不要在您的程式碼中直接使用它們,因為生成和實現細節可能會在未來的版本中發生變化。

Repository 元資料

AOT 處理內省查詢方法並收集有關儲存庫查詢的元資料。Spring Data 將此元資料儲存在與源儲存庫在同一包中同名的 JSON 檔案中。儲存庫 JSON 元資料包含有關查詢和片段的詳細資訊。以下儲存庫的示例如下所示

  • 元資料

  • 儲存庫

{
  "name": "example.springdata.UserRepository",
  "module": "JDBC",
  "type": "IMPERATIVE",
  "methods": [
    {
      "name": "findBy",
      "signature": "public abstract java.util.List<example.springdata.User> example.springdata.UserRepository.findBy()",
      "query": {
        "query": "SELECT * FROM User"
      }
    },
    {
      "name": "findByLastnameStartingWith",
      "signature": "public abstract org.springframework.data.domain.Page<example.springdata.User> example.springdata.UserRepository.findByLastnameStartingWith(java.lang.String,org.springframework.data.domain.Pageable)",
      "query": {
        "query": "SELECT * FROM User u WHERE lastname LIKE :lastname",
        "count-query": "SELECT COUNT(*) FROM User WHERE lastname LIKE :lastname"
      }
    },
    {
      "name": "findByEmailAddress",
      "signature": "public abstract example.springdata.User example.springdata.UserRepository.findByEmailAddress(java.lang.String)",
      "query": {
        "query": "select * from User where emailAddress = ?1"
      }
    },
interface UserRepository extends CrudRepository<User, Integer> {

  List<User> findBy();

  Page<User> findByLastnameStartingWith(String lastname, Pageable page);

  @Query("select * from User where emailAddress = ?1")
  User findByEmailAddress(String username);
}

JSON 元資料的建立可以透過 spring.aot.repositories.metadata.enabled 標誌控制。

原生映象執行時提示

將應用程式作為原生映象執行需要比常規 JVM 執行時更多的資訊。Spring Data 在 AOT 處理期間為原生映象使用貢獻了 執行時提示。這些提示特別適用於

  • 審計

  • ManagedTypes 用於捕獲類路徑掃描的結果

  • Repositories

    • 實體、返回型別和 Spring Data 註解的反射提示

    • Repository 片段

    • Querydsl Q

    • Kotlin 協程支援

  • Web 支援(PagedModel 的 Jackson 提示)

© . This site is unofficial and not affiliated with VMware.