8. GraalVM Native 支持
Spring Framework 6.0 引入了将 Spring 应用程序编译为 GraalVM Native 映像的支持基础设施。 如果您不熟悉 GraalVM,不熟悉它与 JVM 上部署的应用程序有何不同,以及它对 Spring 应用程序意味着什么。 请参阅专用的 Spring Boot 3.0 GraalVM Native Image 支持文档。 Spring Boot 还记录了 Spring 中 GraalVM 支持的已知限制。
8.1. GraphQL Java 元数据
由于应用程序的静态分析是在构建时完成的,因此 如果您的应用程序在运行时查找静态资源、执行反射或创建 JDK 代理,GraalVM 可能需要额外的提示。
GraphQL Java 在运行时执行本机映像可以执行的三项任务:
-
加载用于消息国际化的资源包
-
对 Schema 检查的内部类型的一些思考
-
对应用程序向架构注册的 Java 类型的反射。例如,当 GraphQL Java 从应用程序类型获取属性时,会发生这种情况
前两项通过 Spring 团队贡献给 GraalVM 可访问性元数据存储库的可访问性元数据进行处理。 在构建依赖于 GraphQL Java 的应用程序时,本机编译工具会自动获取此元数据。 这不包括列表中的第三项,因为这些类型由应用程序本身提供,并且必须通过另一种方式发现。
8.2. Native Server 应用程序支持
在典型的 Spring for GraphQL 应用程序中,与 GraphQL 架构相关的 Java 类型在方法签名中公开
作为参数或返回类型。在构建的 Ahead Of Time (提前) 处理阶段,
Spring 或 GraphQL 将使用它来发现
并相应地注册可访问性元数据。
如果您正在构建支持 GraalVM 的 Spring Boot 应用程序,则这一切都会自动为您完成。@Controller
o.s.g.data.method.annotation.support.SchemaMappingBeanFactoryInitializationAotProcessor
如果您的应用程序正在 “手动” 注册数据获取程序,则某些类型将无法被发现。
然后,您应该使用 Spring Framework 的 :@RegisterReflectionForBinding
@Configuration
@RegisterReflectionForBinding(Book.class) (3)
public class GraphQlConfiguration {
@Bean
RuntimeWiringConfigurer customWiringConfigurer(BookRepository bookRepository) { (1)
DataFetcher<Book> dataFetcher = QuerydslDataFetcher.builder(bookRepository).single();
return wiringBuilder -> wiringBuilder
.type("Query", builder -> builder.dataFetcher("book", dataFetcher)); (2)
}
}
1 | 此应用程序声明 a,“手动”添加一个RuntimeWiringConfigurer DataFetcher |
2 | 通过这个 ,将暴露一个类型DataFetcher BookRepository Book |
3 | @RegisterReflectionForBinding 将注册该类型的相关提示,以及作为字段公开的所有类型Book |
8.3. 客户端支持
它不一定作为 bean 存在于应用程序上下文中,并且不会在方法签名中公开模式中使用的 Java 类型。
因此,不能使用上一节中描述的策略。
对于客户端支持,Spring for GraphQL 嵌入了客户端基础设施的相关可访问性元数据。
当涉及到应用程序使用的 Java 类型时,应用程序应该使用与“手动”数据获取器类似的策略,使用以下方法:GraphQlClient
AotProcessor
@RegisterReflectionForBinding
@Component
@RegisterReflectionForBinding(Project.class) (2)
public class ProjectService {
private final GraphQlClient graphQlClient;
public ProjectService(GraphQlClient graphQlClient) {
this.graphQlClient = graphQlClient;
}
public Mono<Project> project(String projectSlug) {
String document = """
query projectWithReleases($projectSlug: ID!) {
project(slug: $projectSlug) {
name
releases {
version
}
}
}
""";
return this.graphQlClient.document(document)
.variable("projectSlug", projectSlug)
.retrieve("project")
.toEntity(Project.class); (1)
}
}
1 | 在 Native 镜像中,我们需要确保在运行时可以执行反射Project |
2 | @RegisterReflectionForBinding 将注册该类型的相关提示,以及作为字段公开的所有类型Project |