Add support for GraphQlExceptionHandler in AOT mode
This commit adds the relevant reflection metadata for supporting `@GraphQlExceptionHandler` annotated methods in controllers and `@ControllerAdvice` beans. Closes gh-677
This commit is contained in:
@@ -20,7 +20,9 @@ import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.aop.SpringProxy;
|
||||
import org.springframework.aot.generate.GenerationContext;
|
||||
@@ -45,10 +47,12 @@ import org.springframework.graphql.data.ArgumentValue;
|
||||
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
|
||||
import org.springframework.graphql.data.method.HandlerMethodArgumentResolverComposite;
|
||||
import org.springframework.graphql.data.method.annotation.BatchMapping;
|
||||
import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandler;
|
||||
import org.springframework.graphql.data.method.annotation.SchemaMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
|
||||
import static org.springframework.core.annotation.MergedAnnotations.SearchStrategy.TYPE_HIERARCHY;
|
||||
|
||||
@@ -58,6 +62,8 @@ import static org.springframework.core.annotation.MergedAnnotations.SearchStrate
|
||||
* <ul>
|
||||
* <li>invocation reflection on {@code @SchemaMapping} and {@code @BatchMapping}
|
||||
* annotated controllers methods
|
||||
* <li>invocation reflection on {@code @GraphQlExceptionHandler} methods
|
||||
* in {@code @Controller} and {@code @ControllerAdvice} beans
|
||||
* <li>binding reflection on controller method arguments, needed for binding or
|
||||
* by the GraphQL Java engine itself
|
||||
* <li>reflection for SpEL support and JDK proxy creation for
|
||||
@@ -85,27 +91,42 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI
|
||||
|
||||
@Override
|
||||
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
|
||||
Class<?>[] controllerTypes = Arrays.stream(beanFactory.getBeanDefinitionNames())
|
||||
List<Class<?>> controllers = new ArrayList<>();
|
||||
List<Class<?>> controllerAdvices = new ArrayList<>();
|
||||
Arrays.stream(beanFactory.getBeanDefinitionNames())
|
||||
.map(beanName -> RegisteredBean.of(beanFactory, beanName).getBeanClass())
|
||||
.filter(this::isController)
|
||||
.toArray(Class<?>[]::new);
|
||||
return new SchemaMappingBeanFactoryInitializationAotContribution(controllerTypes);
|
||||
.forEach(beanClass -> {
|
||||
if (isController(beanClass)) {
|
||||
controllers.add(beanClass);
|
||||
}
|
||||
else if (isControllerAdvice(beanClass)) {
|
||||
controllerAdvices.add(beanClass);
|
||||
}
|
||||
});
|
||||
return new SchemaMappingBeanFactoryInitializationAotContribution(controllers, controllerAdvices);
|
||||
}
|
||||
|
||||
private boolean isController(AnnotatedElement element) {
|
||||
return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(Controller.class);
|
||||
}
|
||||
|
||||
private boolean isControllerAdvice(AnnotatedElement element) {
|
||||
return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(ControllerAdvice.class);
|
||||
}
|
||||
|
||||
|
||||
private static class SchemaMappingBeanFactoryInitializationAotContribution
|
||||
implements BeanFactoryInitializationAotContribution {
|
||||
|
||||
private final Class<?>[] controllers;
|
||||
private final List<Class<?>> controllers;
|
||||
|
||||
private final List<Class<?>> controllerAdvices;
|
||||
|
||||
private final HandlerMethodArgumentResolverComposite argumentResolvers;
|
||||
|
||||
public SchemaMappingBeanFactoryInitializationAotContribution(Class<?>[] controllers) {
|
||||
public SchemaMappingBeanFactoryInitializationAotContribution(List<Class<?>> controllers, List<Class<?>> controllerAdvices) {
|
||||
this.controllers = controllers;
|
||||
this.controllerAdvices = controllerAdvices;
|
||||
this.argumentResolvers = createArgumentResolvers();
|
||||
}
|
||||
|
||||
@@ -120,11 +141,20 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI
|
||||
public void applyTo(GenerationContext context, BeanFactoryInitializationCode initializationCode) {
|
||||
RuntimeHints runtimeHints = context.getRuntimeHints();
|
||||
registerSpringDataSpelSupport(runtimeHints);
|
||||
Arrays.stream(this.controllers).forEach(controller -> {
|
||||
runtimeHints.reflection().registerType(controller);
|
||||
this.controllers.forEach(controller -> {
|
||||
runtimeHints.reflection().registerType(controller, MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
ReflectionUtils.doWithMethods(controller,
|
||||
method -> processSchemaMappingMethod(runtimeHints, method),
|
||||
this::isGraphQlHandlerMethod);
|
||||
ReflectionUtils.doWithMethods(controller,
|
||||
method -> processExceptionHandlerMethod(runtimeHints, method),
|
||||
this::isExceptionHandlerMethod);
|
||||
});
|
||||
this.controllerAdvices.forEach(controllerAdvice -> {
|
||||
runtimeHints.reflection().registerType(controllerAdvice, MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
ReflectionUtils.doWithMethods(controllerAdvice,
|
||||
method -> processExceptionHandlerMethod(runtimeHints, method),
|
||||
this::isExceptionHandlerMethod);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,6 +173,10 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI
|
||||
return annotations.isPresent(SchemaMapping.class) || annotations.isPresent(BatchMapping.class);
|
||||
}
|
||||
|
||||
private boolean isExceptionHandlerMethod(AnnotatedElement element) {
|
||||
return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(GraphQlExceptionHandler.class);
|
||||
}
|
||||
|
||||
private void processSchemaMappingMethod(RuntimeHints runtimeHints, Method method) {
|
||||
runtimeHints.reflection().registerMethod(method, ExecutableMode.INVOKE);
|
||||
for (Parameter parameter : method.getParameters()) {
|
||||
@@ -151,6 +185,10 @@ class SchemaMappingBeanFactoryInitializationAotProcessor implements BeanFactoryI
|
||||
processReturnType(runtimeHints, MethodParameter.forExecutable(method, -1));
|
||||
}
|
||||
|
||||
private void processExceptionHandlerMethod(RuntimeHints runtimeHints, Method method) {
|
||||
runtimeHints.reflection().registerMethod(method, ExecutableMode.INVOKE);
|
||||
}
|
||||
|
||||
private void processMethodParameter(RuntimeHints hints, MethodParameter parameter) {
|
||||
MethodParameterRuntimeHintsRegistrar.fromMethodParameter(this.argumentResolvers, parameter).apply(hints);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
[
|
||||
{
|
||||
"name": "org.springframework.graphql.data.method.annotation.support.AnnotatedControllerExceptionResolver$MethodResolver",
|
||||
"allDeclaredMethods": true,
|
||||
"condition": {
|
||||
"typeReachable": "org.springframework.graphql.data.method.annotation.support.AnnotatedControllerExceptionResolver"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name":"org.springframework.graphql.server.support.GraphQlWebSocketMessage",
|
||||
"allDeclaredFields":true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
* Copyright 2020-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,10 +32,14 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import graphql.GraphQLContext;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.schema.DataFetchingFieldSelectionSet;
|
||||
import org.dataloader.DataLoader;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.graphql.data.method.annotation.*;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -58,13 +62,6 @@ import org.springframework.data.web.ProjectedPayload;
|
||||
import org.springframework.graphql.Author;
|
||||
import org.springframework.graphql.Book;
|
||||
import org.springframework.graphql.data.ArgumentValue;
|
||||
import org.springframework.graphql.data.method.annotation.Argument;
|
||||
import org.springframework.graphql.data.method.annotation.BatchMapping;
|
||||
import org.springframework.graphql.data.method.annotation.ContextValue;
|
||||
import org.springframework.graphql.data.method.annotation.LocalContextValue;
|
||||
import org.springframework.graphql.data.method.annotation.MutationMapping;
|
||||
import org.springframework.graphql.data.method.annotation.QueryMapping;
|
||||
import org.springframework.graphql.data.method.annotation.SchemaMapping;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -92,39 +89,51 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnReturnType() {
|
||||
processController(ReturnTypeController.class);
|
||||
processBeanClasses(ReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ReturnTypeController.class, "bookById");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnInput() {
|
||||
processController(InputController.class);
|
||||
processBeanClasses(InputController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(InputController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(InputController.class, "addBook");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class, BookInput.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnArgumentCollection() {
|
||||
processController(ArgumentCollectionController.class);
|
||||
processBeanClasses(ArgumentCollectionController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ArgumentCollectionController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ArgumentCollectionController.class, "addBooks");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnArgumentValue() {
|
||||
processController(ArgumentValueController.class);
|
||||
processBeanClasses(ArgumentValueController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ArgumentValueController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ArgumentValueController.class, "addBook");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class, BookInput.class);
|
||||
assertThatHintsAreNotRegisteredForTypes(ArgumentValue.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnDataLoaderArgument() {
|
||||
processController(DataLoaderController.class);
|
||||
processBeanClasses(DataLoaderController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(DataLoaderController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(DataLoaderController.class, "authorWithLoader");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Author.class);
|
||||
assertThatHintsAreNotRegisteredForTypes(DataLoader.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnAsyncReturnType() {
|
||||
processController(AsyncReturnTypeController.class);
|
||||
processBeanClasses(AsyncReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(AsyncReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(AsyncReturnTypeController.class, "author");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Author.class);
|
||||
}
|
||||
|
||||
@@ -211,37 +220,49 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnFluxReturnType() {
|
||||
processController(FluxReturnTypeController.class);
|
||||
processBeanClasses(FluxReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(FluxReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(FluxReturnTypeController.class, "batchMappingFlux");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Author.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnMonoMapReturnType() {
|
||||
processController(MonoMapReturnTypeController.class);
|
||||
processBeanClasses(MonoMapReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(MonoMapReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(MonoMapReturnTypeController.class, "batchMappingMono");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class, Author.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnMapReturnType() {
|
||||
processController(MapReturnTypeController.class);
|
||||
processBeanClasses(MapReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(MapReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(MapReturnTypeController.class, "batchMappingMap");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class, Author.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnCollectionReturnType() {
|
||||
processController(CollectionReturnTypeController.class);
|
||||
processBeanClasses(CollectionReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(CollectionReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(CollectionReturnTypeController.class, "batchMappingCollection");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Author.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnCallableCollectionReturnType() {
|
||||
processController(CallableCollectionReturnTypeController.class);
|
||||
processBeanClasses(CallableCollectionReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(CallableCollectionReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(CallableCollectionReturnTypeController.class, "batchMappingCallableCollection");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Author.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerBindingReflectionOnCallableMapReturnType() {
|
||||
processController(CallableMapReturnTypeController.class);
|
||||
processBeanClasses(CallableMapReturnTypeController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(CallableMapReturnTypeController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(CallableMapReturnTypeController.class, "batchMappingCallableMap");
|
||||
assertThatHintsForJavaBeanBindingRegisteredForTypes(Book.class, Author.class);
|
||||
}
|
||||
|
||||
@@ -302,13 +323,17 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void doNotRegisterBindingForContextArguments() {
|
||||
processController(ContextArgumentsController.class);
|
||||
processBeanClasses(ContextArgumentsController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ContextArgumentsController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ContextArgumentsController.class, "dataFetchingEnvironment");
|
||||
assertThatHintsAreNotRegisteredForTypes(GraphQLContext.class, DataFetchingFieldSelectionSet.class, Locale.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void doNotRegisterBindingForAnnotatedContextArguments() {
|
||||
processController(AnnotatedContextArgumentController.class);
|
||||
processBeanClasses(AnnotatedContextArgumentController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(AnnotatedContextArgumentController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(AnnotatedContextArgumentController.class, "contextValue");
|
||||
assertThatHintsAreNotRegisteredForTypes(Book.class);
|
||||
}
|
||||
|
||||
@@ -333,7 +358,7 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void registerSpringDataSpelSupport() {
|
||||
processController();
|
||||
processBeanClasses();
|
||||
TypeReference targetWrapper = TypeReference.of("org.springframework.data.projection.SpelEvaluatingMethodInterceptor$TargetWrapper");
|
||||
assertThat(RuntimeHintsPredicates.reflection().onType(targetWrapper)
|
||||
.withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS,
|
||||
@@ -342,7 +367,9 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void registerProxyForProjection() {
|
||||
processController(ProjectionController.class);
|
||||
processBeanClasses(ProjectionController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ProjectionController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ProjectionController.class, "projection");
|
||||
assertThat(RuntimeHintsPredicates.proxies().forInterfaces(BookProjection.class, TargetAware.class,
|
||||
SpringProxy.class, DecoratingProxy.class)).accepts(generationContext.getRuntimeHints());
|
||||
}
|
||||
@@ -350,7 +377,9 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
@Test
|
||||
void registerProxyForOptionalProjection() {
|
||||
processController(OptionalProjectionController.class);
|
||||
processBeanClasses(OptionalProjectionController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(OptionalProjectionController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(OptionalProjectionController.class, "optionalProjection");
|
||||
assertThat(RuntimeHintsPredicates.proxies().forInterfaces(BookProjection.class, TargetAware.class,
|
||||
SpringProxy.class, DecoratingProxy.class)).accepts(generationContext.getRuntimeHints());
|
||||
}
|
||||
@@ -379,10 +408,46 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ExceptionHandlerTests {
|
||||
|
||||
private void processController(Class<?>... controllers) {
|
||||
@Test
|
||||
void registerReflectionOnControllerExceptionHandler() {
|
||||
processBeanClasses(ExceptionController.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ExceptionController.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ExceptionController.class, "handleIllegalState");
|
||||
}
|
||||
|
||||
@Test
|
||||
void registerReflectionOnControllerAdviceExceptionHandler() {
|
||||
processBeanClasses(ExceptionHandlers.class);
|
||||
assertThatIntrospectionOnMethodsHintRegisteredForType(ExceptionHandlers.class);
|
||||
assertThatInvocationHintRegisteredForMethods(ExceptionHandlers.class, "handleBindException");
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
class ExceptionController {
|
||||
@GraphQlExceptionHandler
|
||||
public GraphQLError handleIllegalState(IllegalStateException exc) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ControllerAdvice
|
||||
class ExceptionHandlers {
|
||||
|
||||
@GraphQlExceptionHandler
|
||||
public GraphQLError handleBindException(BindException exc) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processBeanClasses(Class<?>... beanClasses) {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
for (Class<?> beanClass : controllers) {
|
||||
for (Class<?> beanClass : beanClasses) {
|
||||
beanFactory.registerBeanDefinition(beanClass.getName(), new RootBeanDefinition(beanClass));
|
||||
}
|
||||
BeanFactoryInitializationAotContribution contribution = this.processor.processAheadOfTime(beanFactory);
|
||||
@@ -390,6 +455,20 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
contribution.applyTo(this.generationContext, mock(BeanFactoryInitializationCode.class));
|
||||
}
|
||||
|
||||
private void assertThatIntrospectionOnMethodsHintRegisteredForType(Class<?> type) {
|
||||
Predicate<RuntimeHints> predicate = RuntimeHintsPredicates.reflection()
|
||||
.onType(type).withAnyMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS);
|
||||
assertThat(predicate).accepts(this.generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
private void assertThatInvocationHintRegisteredForMethods(Class<?> type, String... methodNames) {
|
||||
Predicate<RuntimeHints> predicate = Arrays.stream(methodNames)
|
||||
.map(methodName -> (Predicate<RuntimeHints>) RuntimeHintsPredicates.reflection().onMethod(type, methodName))
|
||||
.reduce(Predicate::and)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Could not generate predicate on type " + type + " for methods " + Arrays.toString(methodNames)));
|
||||
assertThat(predicate).accepts(this.generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
private void assertThatHintsForJavaBeanBindingRegisteredForTypes(Class<?>... types) {
|
||||
Predicate<RuntimeHints> predicate = Arrays.stream(types)
|
||||
.map(this::javaBeanBindingOnType)
|
||||
@@ -406,7 +485,6 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
assertThat(predicate).rejects(this.generationContext.getRuntimeHints());
|
||||
}
|
||||
|
||||
|
||||
private Predicate<RuntimeHints> javaBeanBindingOnType(Class<?> type) {
|
||||
Predicate<RuntimeHints> predicate = RuntimeHintsPredicates.reflection().onType(type)
|
||||
.withMemberCategories(MemberCategory.DECLARED_FIELDS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
|
||||
@@ -430,4 +508,4 @@ class SchemaMappingBeanFactoryInitializationAotProcessorTests {
|
||||
return predicate;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user