|
此版本仍在开发中,尚未被视为稳定版。如需最新稳定版,请使用 Spring Data Commons 4.0.4! |
预先优化
本章介绍 Spring Data 的预编译(Ahead of Time,AOT)优化,这些优化基于Spring 的预编译优化。
提前编译代码生成
提前编译(AOT)代码生成不仅限于与 GraalVM Native Image 配合使用,它在常规部署中也能带来优势,并有助于优化 JVM 上的启动性能。
|
通过AOT优化,某些决策(例如数据库方言)将在构建时被固化,并直接包含在应用程序的配置中。 |
如果启用了预先编译(Ahead of Time compilation),Spring Data 可以(取决于实际使用的模块)在构建的 AOT 阶段贡献多个组件。
-
生成的类型/属性访问器的字节码
-
已定义的 Repository 接口的源代码
-
以 JSON 格式表示的仓库元数据
上述每一项默认都是启用的。 然而,用户可以通过以下选项对配置进行微调。
|
用于控制是否为生成的类型/属性访问器贡献字节码的布尔标志 |
|
以逗号分隔的完全限定类名(FQCN)列表,用于为生成的类型/属性访问器提供字节码。
支持使用 Ant 风格的包含模式来匹配包名(例如 |
|
以逗号分隔的完全限定类名(FQCN)列表,用于跳过为生成的类型/属性访问器贡献字节码。
支持 Ant 风格的排除模式,可匹配包名(例如 |
|
用于控制是否为仓库接口生成源代码的布尔标志 |
|
用于控制是否为特定模块(例如 |
|
用于控制是否包含查询方法和实际查询字符串的 JSON 仓库元数据的布尔标志。
需要启用 |
提前编译存储库
|
提前编译(Ahead of Time)仓库仅适用于某些模块的命令式(非响应式)仓库接口。 符合资格的查询方法的判定标准因具体实现模块而异。 |
AOT 仓库是对 AOT 处理的一种扩展,通过预生成符合条件的查询方法实现。 对于开发者而言,查询方法在其调用时所执行的底层查询是不透明的。 AOT 仓库基于在构建时已知的派生查询、注解查询和命名查询,提供查询方法的实现。 此优化将查询方法的处理从运行时移至构建时,从而显著提升性能,因为应用程序每次启动时不再需要通过反射来分析查询方法。
生成的 AOT 仓库片段遵循命名规则 <Repository FQCN>Impl__AotRepository,并放置在与仓库接口相同的包中。
|
请将AOT仓库类视为内部优化。 不要在您的代码中直接使用它们,因为生成方式和实现细节在未来版本中可能会发生变化。 |
仓库元数据
AOT 处理会内省查询方法,并收集有关仓库查询的元数据。 Spring Data 将这些元数据存储在 JSON 文件中,文件名与源仓库相同,并位于同一包内。 仓库 JSON 元数据包含有关查询和片段的详细信息。 以下展示了针对下列仓库的一个示例:
-
Metadata
-
Repository
{
"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);
}
|
可以通过 |
原生镜像运行时提示
与常规的 JVM 运行时相比,以原生镜像(native image)方式运行应用程序需要额外的信息。 Spring Data 在 AOT(提前编译)处理过程中会为原生镜像的使用提供运行时提示(Runtime Hints)。 这些提示尤其包括:
-
审计
-
ManagedTypes用于捕获类路径扫描的结果 -
仓库
-
实体、返回类型和 Spring Data 注解的反射提示
-
仓库片段
-
Querydsl
Q类 -
Kotlin 协程支持
-
-
Web 支持(针对
PagedModel的 Jackson 提示)