1
1
/*
2
- * Copyright 2020-2022 the original author or authors.
2
+ * Copyright 2020-2023 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
47
47
import org .springframework .graphql .data .method .annotation .BatchMapping ;
48
48
import org .springframework .graphql .data .method .annotation .SchemaMapping ;
49
49
import org .springframework .stereotype .Controller ;
50
- import org .springframework .util .Assert ;
51
50
import org .springframework .util .ClassUtils ;
52
51
import org .springframework .util .ReflectionUtils ;
53
52
57
56
* {@link BeanFactoryInitializationAotProcessor} implementation for registering
58
57
* runtime hints discoverable through GraphQL controllers, such as:
59
58
* <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.
64
66
* </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.
71
74
*
72
75
* @author Brian Clozel
73
76
* @see org.springframework.graphql.data.method.HandlerMethodArgumentResolver
@@ -93,7 +96,9 @@ private boolean isController(AnnotatedElement element) {
93
96
return MergedAnnotations .from (element , TYPE_HIERARCHY ).isPresent (Controller .class );
94
97
}
95
98
96
- private static class SchemaMappingBeanFactoryInitializationAotContribution implements BeanFactoryInitializationAotContribution {
99
+
100
+ private static class SchemaMappingBeanFactoryInitializationAotContribution
101
+ implements BeanFactoryInitializationAotContribution {
97
102
98
103
private final Class <?>[] controllers ;
99
104
@@ -105,21 +110,21 @@ public SchemaMappingBeanFactoryInitializationAotContribution(Class<?>[] controll
105
110
}
106
111
107
112
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 ();
114
117
}
115
118
116
119
@ 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 ();
119
122
registerSpringDataSpelSupport (runtimeHints );
120
123
Arrays .stream (this .controllers ).forEach (controller -> {
121
124
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 );
123
128
});
124
129
}
125
130
@@ -134,9 +139,8 @@ private void registerSpringDataSpelSupport(RuntimeHints runtimeHints) {
134
139
}
135
140
136
141
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 );
140
144
}
141
145
142
146
private void processSchemaMappingMethod (RuntimeHints runtimeHints , Method method ) {
@@ -147,43 +151,46 @@ private void processSchemaMappingMethod(RuntimeHints runtimeHints, Method method
147
151
processReturnType (runtimeHints , MethodParameter .forExecutable (method , -1 ));
148
152
}
149
153
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 );
153
156
}
154
157
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 );
157
160
}
158
161
159
162
}
160
163
164
+
161
165
@ FunctionalInterface
162
166
private interface MethodParameterRuntimeHintsRegistrar {
163
167
164
168
BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar ();
165
169
166
170
void apply (RuntimeHints runtimeHints );
167
171
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 );
173
179
}
174
- if (argumentResolver instanceof DataLoaderMethodArgumentResolver ) {
175
- return new DataLoaderHints (methodParameter );
180
+ if (resolver instanceof DataLoaderMethodArgumentResolver ) {
181
+ return new DataLoaderHints (parameter );
176
182
}
177
183
if (springDataPresent ) {
178
- if (argumentResolver instanceof ProjectedPayloadMethodArgumentResolver ) {
179
- return new ProjectedPayloadHints (methodParameter );
184
+ if (resolver instanceof ProjectedPayloadMethodArgumentResolver ) {
185
+ return new ProjectedPayloadHints (parameter );
180
186
}
181
187
}
182
188
return new NoHintsRequired ();
183
189
}
184
190
185
191
}
186
192
193
+
187
194
private static class NoHintsRequired implements MethodParameterRuntimeHintsRegistrar {
188
195
189
196
@ Override
@@ -192,6 +199,7 @@ public void apply(RuntimeHints runtimeHints) {
192
199
}
193
200
}
194
201
202
+
195
203
private static class ArgumentBindingHints implements MethodParameterRuntimeHintsRegistrar {
196
204
197
205
private final MethodParameter methodParameter ;
@@ -210,6 +218,7 @@ public void apply(RuntimeHints runtimeHints) {
210
218
}
211
219
}
212
220
221
+
213
222
private static class DataLoaderHints implements MethodParameterRuntimeHintsRegistrar {
214
223
215
224
private final MethodParameter methodParameter ;
@@ -219,12 +228,13 @@ public DataLoaderHints(MethodParameter methodParameter) {
219
228
}
220
229
221
230
@ 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 ());
225
234
}
226
235
}
227
236
237
+
228
238
private static class ProjectedPayloadHints implements MethodParameterRuntimeHintsRegistrar {
229
239
230
240
private final MethodParameter methodParameter ;
@@ -234,10 +244,10 @@ public ProjectedPayloadHints(MethodParameter methodParameter) {
234
244
}
235
245
236
246
@ Override
237
- public void apply (RuntimeHints runtimeHints ) {
247
+ public void apply (RuntimeHints hints ) {
238
248
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 );
241
251
}
242
252
}
243
253
0 commit comments