Skip to content

Commit f237842

Browse files
committed
Polishing
1 parent 287dab0 commit f237842

File tree

4 files changed

+103
-95
lines changed

4 files changed

+103
-95
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/HandlerMethodArgumentResolverComposite.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,9 +27,8 @@
2727
import org.springframework.lang.Nullable;
2828

2929
/**
30-
* Resolves method parameters by delegating to a list of registered
31-
* {@link HandlerMethodArgumentResolver HandlerMethodArgumentResolver}'s.
32-
* Previously resolved method parameters are cached for faster lookups.
30+
* Container for a list of resolvers that looks for one that supports a given
31+
* method parameter type, and delegates to it.
3332
*
3433
* @author Rossen Stoyanchev
3534
* @since 1.0.0
@@ -63,7 +62,7 @@ public List<HandlerMethodArgumentResolver> getResolvers() {
6362
*/
6463
@Override
6564
public boolean supportsParameter(MethodParameter parameter) {
66-
return getArgumentResolver(parameter) != null;
65+
return (getArgumentResolver(parameter) != null);
6766
}
6867

6968
/**
@@ -77,8 +76,7 @@ public boolean supportsParameter(MethodParameter parameter) {
7776
public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment environment) throws Exception {
7877
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
7978
if (resolver == null) {
80-
throw new IllegalArgumentException("Unsupported parameter type [" +
81-
parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
79+
throw new IllegalArgumentException("Unsupported parameter [" + parameter + "].");
8280
}
8381
return resolver.resolveArgument(parameter, environment);
8482
}
@@ -89,17 +87,14 @@ public Object resolveArgument(MethodParameter parameter, DataFetchingEnvironment
8987
*/
9088
@Nullable
9189
public HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
92-
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
93-
if (result == null) {
90+
return this.argumentResolverCache.computeIfAbsent(parameter, p -> {
9491
for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
9592
if (resolver.supportsParameter(parameter)) {
96-
result = resolver;
97-
this.argumentResolverCache.put(parameter, result);
98-
break;
93+
return resolver;
9994
}
10095
}
101-
}
102-
return result;
96+
return null;
97+
});
10398
}
10499

105100
}

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerConfigurer.java

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,19 @@ public class AnnotatedControllerConfigurer
122122
private final FormattingConversionService conversionService = new DefaultFormattingConversionService();
123123

124124
@Nullable
125-
private Executor executor;
125+
private HandlerMethodArgumentResolverComposite argumentResolvers;
126126

127127
@Nullable
128-
private ApplicationContext applicationContext;
128+
private ValidationHelper validationHelper;
129129

130130
@Nullable
131-
private HandlerMethodArgumentResolverComposite argumentResolvers;
131+
private AnnotatedControllerExceptionResolver exceptionResolver;
132132

133133
@Nullable
134-
private ValidationHelper validationHelper;
134+
private Executor executor;
135135

136136
@Nullable
137-
private AnnotatedControllerExceptionResolver exceptionResolver;
137+
private ApplicationContext applicationContext;
138138

139139

140140
/**
@@ -147,31 +147,10 @@ public void addFormatterRegistrar(FormatterRegistrar registrar) {
147147
registrar.registerFormatters(this.conversionService);
148148
}
149149

150-
/**
151-
* Configure an {@link Executor} to use for asynchronous handling of
152-
* {@link Callable} return values from controller methods.
153-
* <p>By default, this is not set in which case controller methods with a
154-
* {@code Callable} return value cannot be registered.
155-
* @param executor the executor to use
156-
*/
157-
public void setExecutor(Executor executor) {
158-
this.executor = executor;
159-
}
160-
161-
/**
162-
* Configure an initializer that configures the {@link DataBinder} before the binding process.
163-
* @param consumer the data binder initializer
164-
* @since 1.0.1
165-
* @deprecated this property is deprecated, ignored, and should not be
166-
* necessary as a {@link DataBinder} is no longer used to bind arguments
167-
*/
168-
@Deprecated(since = "1.1.0", forRemoval = true)
169-
public void setDataBinderInitializer(@Nullable Consumer<DataBinder> consumer) {
170-
}
171-
172-
@Override
173-
public void setApplicationContext(ApplicationContext applicationContext) {
174-
this.applicationContext = applicationContext;
150+
HandlerMethodArgumentResolverComposite getArgumentResolvers() {
151+
Assert.notNull(this.argumentResolvers,
152+
"HandlerMethodArgumentResolverComposite is not yet initialized, was afterPropertiesSet called?");
153+
return this.argumentResolvers;
175154
}
176155

177156
/**
@@ -189,15 +168,39 @@ public void setApplicationContext(ApplicationContext applicationContext) {
189168
* @since 1.2
190169
*/
191170
public DataFetcherExceptionResolver getExceptionResolver() {
192-
Assert.notNull(this.exceptionResolver, "ExceptionResolver is not initialized, was afterPropertiesSet called?");
171+
Assert.notNull(this.exceptionResolver,
172+
"DataFetcherExceptionResolver is not yet initialized, was afterPropertiesSet called?");
193173
return (ex, env) -> this.exceptionResolver.resolveException(ex, env, null);
194174
}
195175

196-
@Nullable
197-
HandlerMethodArgumentResolverComposite getArgumentResolvers() {
198-
return this.argumentResolvers;
176+
/**
177+
* Configure an initializer that configures the {@link DataBinder} before the binding process.
178+
* @param consumer the data binder initializer
179+
* @since 1.0.1
180+
* @deprecated this property is deprecated, ignored, and should not be
181+
* necessary as a {@link DataBinder} is no longer used to bind arguments
182+
*/
183+
@Deprecated(since = "1.1.0", forRemoval = true)
184+
public void setDataBinderInitializer(@Nullable Consumer<DataBinder> consumer) {
199185
}
200186

187+
/**
188+
* Configure an {@link Executor} to use for asynchronous handling of
189+
* {@link Callable} return values from controller methods.
190+
* <p>By default, this is not set in which case controller methods with a
191+
* {@code Callable} return value cannot be registered.
192+
* @param executor the executor to use
193+
*/
194+
public void setExecutor(Executor executor) {
195+
this.executor = executor;
196+
}
197+
198+
@Override
199+
public void setApplicationContext(ApplicationContext applicationContext) {
200+
this.applicationContext = applicationContext;
201+
}
202+
203+
201204
@Override
202205
public void afterPropertiesSet() {
203206

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingBeanFactoryInitializationAotProcessor.java

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -47,7 +47,6 @@
4747
import org.springframework.graphql.data.method.annotation.BatchMapping;
4848
import org.springframework.graphql.data.method.annotation.SchemaMapping;
4949
import org.springframework.stereotype.Controller;
50-
import org.springframework.util.Assert;
5150
import org.springframework.util.ClassUtils;
5251
import org.springframework.util.ReflectionUtils;
5352

@@ -57,17 +56,21 @@
5756
* {@link BeanFactoryInitializationAotProcessor} implementation for registering
5857
* runtime hints discoverable through GraphQL controllers, such as:
5958
* <ul>
60-
* <li>invocation reflection on {@code @SchemaMapping} and {@code @BatchMapping} annotated controllers methods
61-
* <li>binding reflection on controller method arguments, needed for binding or by the GraphQL Java engine itself
62-
* <li>reflection for SpEL support and JDK proxy creation for {@code @ProjectedPayload} projections,
63-
* if Spring Data Commons is present on the classpath.
59+
* <li>invocation reflection on {@code @SchemaMapping} and {@code @BatchMapping}
60+
* annotated controllers methods
61+
* <li>binding reflection on controller method arguments, needed for binding or
62+
* by the GraphQL Java engine itself
63+
* <li>reflection for SpEL support and JDK proxy creation for
64+
* {@code @ProjectedPayload} projections, if Spring Data Commons is present on
65+
* the classpath.
6466
* </ul>
65-
* <p>This processor is using a {@link HandlerMethodArgumentResolver} resolution mechanism similar
66-
* to the one used in {@link AnnotatedControllerConfigurer}. The type of runtime hints registered
67-
* for each method argument depends on the {@link HandlerMethodArgumentResolver} resolved.
68-
* <p>Manual registration of {@link graphql.schema.DataFetcher} cannot be detected by this
69-
* processor; developers will need to declare bound types with {@link RegisterReflectionForBinding}
70-
* annotations on their configuration class.
67+
* <p>This processor is using a {@link HandlerMethodArgumentResolver} resolution
68+
* mechanism similar to the one used in {@link AnnotatedControllerConfigurer}.
69+
* The type of runtime hints registered for each method argument depends on the
70+
* {@link HandlerMethodArgumentResolver} resolved.
71+
* <p>Manual registration of {@link graphql.schema.DataFetcher} cannot be detected
72+
* by this processor; developers will need to declare bound types with
73+
* {@link RegisterReflectionForBinding} annotations on their configuration class.
7174
*
7275
* @author Brian Clozel
7376
* @see org.springframework.graphql.data.method.HandlerMethodArgumentResolver
@@ -93,7 +96,9 @@ private boolean isController(AnnotatedElement element) {
9396
return MergedAnnotations.from(element, TYPE_HIERARCHY).isPresent(Controller.class);
9497
}
9598

96-
private static class SchemaMappingBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotContribution {
99+
100+
private static class SchemaMappingBeanFactoryInitializationAotContribution
101+
implements BeanFactoryInitializationAotContribution {
97102

98103
private final Class<?>[] controllers;
99104

@@ -105,21 +110,21 @@ public SchemaMappingBeanFactoryInitializationAotContribution(Class<?>[] controll
105110
}
106111

107112
private HandlerMethodArgumentResolverComposite createArgumentResolvers() {
108-
AnnotatedControllerConfigurer controllerConfigurer = new AnnotatedControllerConfigurer();
109-
controllerConfigurer.setApplicationContext(new StaticApplicationContext());
110-
controllerConfigurer.afterPropertiesSet();
111-
HandlerMethodArgumentResolverComposite argumentResolverComposite = controllerConfigurer.getArgumentResolvers();
112-
Assert.notNull(argumentResolverComposite, "argument resolvers should not be null");
113-
return argumentResolverComposite;
113+
AnnotatedControllerConfigurer configurer = new AnnotatedControllerConfigurer();
114+
configurer.setApplicationContext(new StaticApplicationContext());
115+
configurer.afterPropertiesSet();
116+
return configurer.getArgumentResolvers();
114117
}
115118

116119
@Override
117-
public void applyTo(GenerationContext generationContext, BeanFactoryInitializationCode beanFactoryInitializationCode) {
118-
RuntimeHints runtimeHints = generationContext.getRuntimeHints();
120+
public void applyTo(GenerationContext context, BeanFactoryInitializationCode initializationCode) {
121+
RuntimeHints runtimeHints = context.getRuntimeHints();
119122
registerSpringDataSpelSupport(runtimeHints);
120123
Arrays.stream(this.controllers).forEach(controller -> {
121124
runtimeHints.reflection().registerType(controller);
122-
ReflectionUtils.doWithMethods(controller, method -> processSchemaMappingMethod(runtimeHints, method), this::isGraphQlHandlerMethod);
125+
ReflectionUtils.doWithMethods(controller,
126+
method -> processSchemaMappingMethod(runtimeHints, method),
127+
this::isGraphQlHandlerMethod);
123128
});
124129
}
125130

@@ -134,9 +139,8 @@ private void registerSpringDataSpelSupport(RuntimeHints runtimeHints) {
134139
}
135140

136141
private boolean isGraphQlHandlerMethod(AnnotatedElement element) {
137-
MergedAnnotations mergedAnnotations = MergedAnnotations.from(element, TYPE_HIERARCHY);
138-
return mergedAnnotations.isPresent(SchemaMapping.class)
139-
|| mergedAnnotations.isPresent(BatchMapping.class);
142+
MergedAnnotations annotations = MergedAnnotations.from(element, TYPE_HIERARCHY);
143+
return annotations.isPresent(SchemaMapping.class) || annotations.isPresent(BatchMapping.class);
140144
}
141145

142146
private void processSchemaMappingMethod(RuntimeHints runtimeHints, Method method) {
@@ -147,43 +151,46 @@ private void processSchemaMappingMethod(RuntimeHints runtimeHints, Method method
147151
processReturnType(runtimeHints, MethodParameter.forExecutable(method, -1));
148152
}
149153

150-
private void processMethodParameter(RuntimeHints runtimeHints, MethodParameter methodParameter) {
151-
MethodParameterRuntimeHintsRegistrar.fromMethodParameter(this.argumentResolvers, methodParameter)
152-
.apply(runtimeHints);
154+
private void processMethodParameter(RuntimeHints hints, MethodParameter parameter) {
155+
MethodParameterRuntimeHintsRegistrar.fromMethodParameter(this.argumentResolvers, parameter).apply(hints);
153156
}
154157

155-
private void processReturnType(RuntimeHints runtimeHints, MethodParameter methodParameter) {
156-
new ArgumentBindingHints(methodParameter).apply(runtimeHints);
158+
private void processReturnType(RuntimeHints hints, MethodParameter parameter) {
159+
new ArgumentBindingHints(parameter).apply(hints);
157160
}
158161

159162
}
160163

164+
161165
@FunctionalInterface
162166
private interface MethodParameterRuntimeHintsRegistrar {
163167

164168
BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
165169

166170
void apply(RuntimeHints runtimeHints);
167171

168-
static MethodParameterRuntimeHintsRegistrar fromMethodParameter(HandlerMethodArgumentResolverComposite argumentResolvers, MethodParameter methodParameter) {
169-
HandlerMethodArgumentResolver argumentResolver = argumentResolvers.getArgumentResolver(methodParameter);
170-
if (argumentResolver instanceof ArgumentMethodArgumentResolver
171-
|| argumentResolver instanceof ArgumentsMethodArgumentResolver) {
172-
return new ArgumentBindingHints(methodParameter);
172+
static MethodParameterRuntimeHintsRegistrar fromMethodParameter(
173+
HandlerMethodArgumentResolverComposite resolvers, MethodParameter parameter) {
174+
175+
HandlerMethodArgumentResolver resolver = resolvers.getArgumentResolver(parameter);
176+
if (resolver instanceof ArgumentMethodArgumentResolver
177+
|| resolver instanceof ArgumentsMethodArgumentResolver) {
178+
return new ArgumentBindingHints(parameter);
173179
}
174-
if (argumentResolver instanceof DataLoaderMethodArgumentResolver) {
175-
return new DataLoaderHints(methodParameter);
180+
if (resolver instanceof DataLoaderMethodArgumentResolver) {
181+
return new DataLoaderHints(parameter);
176182
}
177183
if (springDataPresent) {
178-
if (argumentResolver instanceof ProjectedPayloadMethodArgumentResolver) {
179-
return new ProjectedPayloadHints(methodParameter);
184+
if (resolver instanceof ProjectedPayloadMethodArgumentResolver) {
185+
return new ProjectedPayloadHints(parameter);
180186
}
181187
}
182188
return new NoHintsRequired();
183189
}
184190

185191
}
186192

193+
187194
private static class NoHintsRequired implements MethodParameterRuntimeHintsRegistrar {
188195

189196
@Override
@@ -192,6 +199,7 @@ public void apply(RuntimeHints runtimeHints) {
192199
}
193200
}
194201

202+
195203
private static class ArgumentBindingHints implements MethodParameterRuntimeHintsRegistrar {
196204

197205
private final MethodParameter methodParameter;
@@ -210,6 +218,7 @@ public void apply(RuntimeHints runtimeHints) {
210218
}
211219
}
212220

221+
213222
private static class DataLoaderHints implements MethodParameterRuntimeHintsRegistrar {
214223

215224
private final MethodParameter methodParameter;
@@ -219,12 +228,13 @@ public DataLoaderHints(MethodParameter methodParameter) {
219228
}
220229

221230
@Override
222-
public void apply(RuntimeHints runtimeHints) {
223-
bindingRegistrar.registerReflectionHints(runtimeHints.reflection(),
224-
this.methodParameter.nested().getNestedGenericParameterType());
231+
public void apply(RuntimeHints hints) {
232+
bindingRegistrar.registerReflectionHints(
233+
hints.reflection(), this.methodParameter.nested().getNestedGenericParameterType());
225234
}
226235
}
227236

237+
228238
private static class ProjectedPayloadHints implements MethodParameterRuntimeHintsRegistrar {
229239

230240
private final MethodParameter methodParameter;
@@ -234,10 +244,10 @@ public ProjectedPayloadHints(MethodParameter methodParameter) {
234244
}
235245

236246
@Override
237-
public void apply(RuntimeHints runtimeHints) {
247+
public void apply(RuntimeHints hints) {
238248
Class<?> parameterType = this.methodParameter.nestedIfOptional().getNestedParameterType();
239-
runtimeHints.reflection().registerType(parameterType);
240-
runtimeHints.proxies().registerJdkProxy(parameterType, TargetAware.class, SpringProxy.class, DecoratingProxy.class);
249+
hints.reflection().registerType(parameterType);
250+
hints.proxies().registerJdkProxy(parameterType, TargetAware.class, SpringProxy.class, DecoratingProxy.class);
241251
}
242252
}
243253

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ private AnnotatedControllerExceptionResolver exceptionResolver(ApplicationContex
148148
configurer.setApplicationContext(applicationContext);
149149
configurer.afterPropertiesSet();
150150

151-
HandlerMethodArgumentResolverComposite argumentResolvers = configurer.getArgumentResolvers();
152-
AnnotatedControllerExceptionResolver resolver = new AnnotatedControllerExceptionResolver(argumentResolvers);
151+
HandlerMethodArgumentResolverComposite resolvers = configurer.getArgumentResolvers();
152+
AnnotatedControllerExceptionResolver resolver = new AnnotatedControllerExceptionResolver(resolvers);
153153
resolver.registerControllerAdvice(applicationContext);
154154
return resolver;
155155
}

0 commit comments

Comments
 (0)