GraalVM 原生支持

Spring Framework 6.0 引入了将 Spring 应用程序编译为 GraalVM Native 镜像的支持基础设施。如果您不熟悉 GraalVM,不了解它与在 JVM 上部署的应用程序有何不同,以及这对 Spring 应用程序意味着什么,请参阅专门的 Spring Boot 3.x GraalVM Native Image 支持文档。Spring Boot 也记录了 Spring 中 GraalVM 支持的已知限制

GraphQL Java 元数据

由于 您的应用程序的静态分析是在构建时完成的,如果您的应用程序正在查找静态资源、执行反射或在运行时创建 JDK 代理,GraalVM 可能需要额外的提示。

GraphQL Java 在运行时执行三项对 Native 镜像敏感的任务

  1. 加载用于消息国际化的资源包

  2. 对内部类型进行一些反射以进行模式检查

  3. 对您的应用程序注册到模式中的 Java 类型进行反射。例如,当 GraphQL Java 从应用程序类型中获取属性时就会发生这种情况

前两项通过 Spring 团队贡献给 GraalVM 可达性元数据仓库的可达性元数据进行处理。当构建依赖于 GraphQL Java 的应用程序时,本机编译工具会自动获取此元数据。这不包括我们列表中的第三项,因为这些类型是由应用程序本身提供的,必须通过其他方式发现。

Native 服务器应用程序支持

在典型的 Spring for GraphQL 应用程序中,与 GraphQL 模式绑定的 Java 类型在 @Controller 方法签名中作为参数或返回类型公开。在构建的 预处理阶段,Spring 或 GraphQL 将使用其 o.s.g.data.method.annotation.support.SchemaMappingBeanFactoryInitializationAotProcessor 来发现相关类型并相应地注册可达性元数据。如果您正在构建一个支持 GraalVM 的 Spring Boot 应用程序,这一切都将自动为您完成。

如果您的应用程序“手动”注册数据获取器,则某些类型因此无法发现。您应该使用 Spring Framework 的 @RegisterReflectionForBinding 注册它们

import graphql.schema.DataFetcher;

import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.data.query.QuerydslDataFetcher;
import org.springframework.graphql.execution.RuntimeWiringConfigurer;

@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 此应用程序声明了一个“手动”添加 DataFetcherRuntimeWiringConfigurer
2 通过此 DataFetcherBookRepository 将暴露一个 Book 类型
3 @RegisterReflectionForBinding 将为 Book 类型和所有作为字段暴露的类型注册相关提示

客户端支持

GraphQlClient 不一定作为 Bean 出现在应用程序上下文中,并且它不以方法签名的方式暴露模式中使用的 Java 类型。因此,上面章节中描述的 AotProcessor 策略无法使用。对于客户端支持,Spring for GraphQL 嵌入了 客户端基础设施的相关可达性元数据。至于应用程序使用的 Java 类型,应用程序应使用类似于“手动”数据获取器的策略,即使用 @RegisterReflectionForBinding

import reactor.core.publisher.Mono;

import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.graphql.client.GraphQlClient;
import org.springframework.stereotype.Component;

@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 类型和所有作为字段暴露的类型注册相关提示
© . This site is unofficial and not affiliated with VMware.