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.