预先优化

本章介绍了 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.