Skip to content

Commit 5aa8583

Browse files
committed
Add shortcut to register an executable with a mode
See gh-29011
1 parent c164b91 commit 5aa8583

File tree

8 files changed

+56
-29
lines changed

8 files changed

+56
-29
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import org.springframework.aot.generate.GeneratedMethod;
4747
import org.springframework.aot.generate.GenerationContext;
4848
import org.springframework.aot.generate.MethodReference;
49-
import org.springframework.aot.hint.ExecutableHint;
5049
import org.springframework.aot.hint.ExecutableMode;
5150
import org.springframework.aot.hint.FieldHint;
5251
import org.springframework.aot.hint.RuntimeHints;
@@ -914,9 +913,6 @@ private static class AotContribution implements BeanRegistrationAotContribution
914913

915914
private static final String INSTANCE_PARAMETER = "instance";
916915

917-
private static final Consumer<ExecutableHint.Builder> INTROSPECT = builder -> builder
918-
.withMode(ExecutableMode.INTROSPECT);
919-
920916
private static final Consumer<FieldHint.Builder> ALLOW_WRITE = builder -> builder
921917
.allowWrite(true);
922918

@@ -1024,7 +1020,7 @@ private CodeBlock generateMethodStatementForMethod(Method method,
10241020
INSTANCE_PARAMETER);
10251021
}
10261022
else {
1027-
hints.reflection().registerMethod(method, INTROSPECT);
1023+
hints.reflection().registerMethod(method, ExecutableMode.INTROSPECT);
10281024
CodeBlock arguments = new AutowiredArgumentsCodeGenerator(this.target,
10291025
method).generateCode(method.getParameterTypes());
10301026
CodeBlock injectionCode = CodeBlock.of("args -> $L.$L($L)",

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionPropertiesCodeGenerator.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@
2828
import java.util.Objects;
2929
import java.util.function.BiFunction;
3030
import java.util.function.BiPredicate;
31-
import java.util.function.Consumer;
3231
import java.util.function.Function;
3332
import java.util.function.Predicate;
3433

3534
import org.springframework.aot.generate.GeneratedMethods;
36-
import org.springframework.aot.hint.ExecutableHint;
3735
import org.springframework.aot.hint.ExecutableMode;
3836
import org.springframework.aot.hint.RuntimeHints;
3937
import org.springframework.beans.BeanInfoFactory;
@@ -83,8 +81,6 @@ class BeanDefinitionPropertiesCodeGenerator {
8381

8482
private static final String BEAN_DEFINITION_VARIABLE = BeanRegistrationCodeFragments.BEAN_DEFINITION_VARIABLE;
8583

86-
private static final Consumer<ExecutableHint.Builder> INVOKE_HINT = hint -> hint.withMode(ExecutableMode.INVOKE);
87-
8884
private static final BeanInfoFactory beanInfoFactory = new ExtendedBeanInfoFactory();
8985

9086
private final RuntimeHints hints;
@@ -195,7 +191,7 @@ private void addPropertyValues(CodeBlock.Builder code,
195191
for (PropertyValue propertyValue : propertyValues) {
196192
Method writeMethod = writeMethods.get(propertyValue.getName());
197193
if (writeMethod != null) {
198-
this.hints.reflection().registerMethod(writeMethod, INVOKE_HINT);
194+
this.hints.reflection().registerMethod(writeMethod, ExecutableMode.INVOKE);
199195
}
200196
}
201197
}

spring-beans/src/main/java/org/springframework/beans/factory/aot/InstanceSupplierCodeGenerator.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import org.springframework.aot.generate.GeneratedMethod;
2929
import org.springframework.aot.generate.GeneratedMethods;
3030
import org.springframework.aot.generate.GenerationContext;
31-
import org.springframework.aot.hint.ExecutableHint;
3231
import org.springframework.aot.hint.ExecutableMode;
3332
import org.springframework.beans.factory.support.InstanceSupplier;
3433
import org.springframework.beans.factory.support.RegisteredBean;
@@ -69,9 +68,6 @@ class InstanceSupplierCodeGenerator {
6968

7069
private static final CodeBlock NO_ARGS = CodeBlock.of("");
7170

72-
private static final Consumer<ExecutableHint.Builder> INTROSPECT = hint -> hint
73-
.withMode(ExecutableMode.INTROSPECT);
74-
7571

7672
private final GenerationContext generationContext;
7773

@@ -128,7 +124,7 @@ private CodeBlock generateCodeForAccessibleConstructor(String beanName, Class<?>
128124
Constructor<?> constructor, boolean dependsOnBean, Class<?> declaringClass) {
129125

130126
this.generationContext.getRuntimeHints().reflection()
131-
.registerConstructor(constructor, INTROSPECT);
127+
.registerConstructor(constructor, ExecutableMode.INTROSPECT);
132128
if (!dependsOnBean && constructor.getParameterCount() == 0) {
133129
if (!this.allowDirectSupplierShortcut) {
134130
return CodeBlock.of("$T.using($T::new)", InstanceSupplier.class,
@@ -225,7 +221,7 @@ private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName,
225221
Class<?> beanClass, Method factoryMethod, Class<?> declaringClass, boolean dependsOnBean) {
226222

227223
this.generationContext.getRuntimeHints().reflection()
228-
.registerMethod(factoryMethod, INTROSPECT);
224+
.registerMethod(factoryMethod, ExecutableMode.INTROSPECT);
229225
if (!dependsOnBean && factoryMethod.getParameterCount() == 0) {
230226
CodeBlock.Builder code = CodeBlock.builder();
231227
code.add("$T.<$T>forFactoryMethod($T.class, $S)", BeanInstanceSupplier.class,

spring-context/src/main/java/org/springframework/context/aot/BindingReflectionHintsRegistrar.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525
import java.lang.reflect.Type;
2626
import java.util.LinkedHashSet;
2727
import java.util.Set;
28-
import java.util.function.Consumer;
2928

3029
import org.apache.commons.logging.Log;
3130
import org.apache.commons.logging.LogFactory;
3231

33-
import org.springframework.aot.hint.ExecutableHint;
3432
import org.springframework.aot.hint.ExecutableMode;
3533
import org.springframework.aot.hint.MemberCategory;
3634
import org.springframework.aot.hint.ReflectionHints;
@@ -54,9 +52,6 @@ public class BindingReflectionHintsRegistrar {
5452

5553
private static final Log logger = LogFactory.getLog(BindingReflectionHintsRegistrar.class);
5654

57-
private static final Consumer<ExecutableHint.Builder> INVOKE = builder -> builder
58-
.withMode(ExecutableMode.INVOKE);
59-
6055
private static final String KOTLIN_COMPANION_SUFFIX = "$Companion";
6156

6257
/**
@@ -127,7 +122,7 @@ private void registerReflectionHints(ReflectionHints hints, Set<Type> seen, Type
127122
}
128123

129124
private void registerRecordHints(ReflectionHints hints, Set<Type> seen, Method method) {
130-
hints.registerMethod(method, INVOKE);
125+
hints.registerMethod(method, ExecutableMode.INVOKE);
131126
MethodParameter methodParameter = MethodParameter.forExecutable(method, -1);
132127
Type methodParameterType = methodParameter.getGenericParameterType();
133128
if (!seen.contains(methodParameterType)) {
@@ -138,7 +133,7 @@ private void registerRecordHints(ReflectionHints hints, Set<Type> seen, Method m
138133
private void registerPropertyHints(ReflectionHints hints, Set<Type> seen, @Nullable Method method, int parameterIndex) {
139134
if (method != null && method.getDeclaringClass() != Object.class
140135
&& method.getDeclaringClass() != Enum.class) {
141-
hints.registerMethod(method, INVOKE);
136+
hints.registerMethod(method, ExecutableMode.INVOKE);
142137
MethodParameter methodParameter = MethodParameter.forExecutable(method, parameterIndex);
143138
Type methodParameterType = methodParameter.getGenericParameterType();
144139
if (!seen.contains(methodParameterType)) {

spring-core/src/main/java/org/springframework/aot/hint/ReflectionHints.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,25 @@ public ReflectionHints registerConstructor(Constructor<?> constructor, Consumer<
158158
typeHint -> typeHint.withConstructor(mapParameters(constructor), constructorHint));
159159
}
160160

161+
/**
162+
* Register the need for reflection on the specified {@link Constructor},
163+
* using the specified {@link ExecutableMode}.
164+
* @param constructor the constructor that requires reflection
165+
* @param mode the requested mode
166+
* @return {@code this}, to facilitate method chaining
167+
*/
168+
public ReflectionHints registerConstructor(Constructor<?> constructor, ExecutableMode mode) {
169+
return registerConstructor(constructor, constructorHint -> constructorHint.withMode(mode));
170+
}
171+
161172
/**
162173
* Register the need for reflection on the specified {@link Constructor},
163174
* enabling {@link ExecutableMode#INVOKE}.
164175
* @param constructor the constructor that requires reflection
165176
* @return {@code this}, to facilitate method chaining
166177
*/
167178
public ReflectionHints registerConstructor(Constructor<?> constructor) {
168-
return registerConstructor(constructor, constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE));
179+
return registerConstructor(constructor, ExecutableMode.INVOKE);
169180
}
170181

171182
/**
@@ -179,14 +190,25 @@ public ReflectionHints registerMethod(Method method, Consumer<ExecutableHint.Bui
179190
typeHint -> typeHint.withMethod(method.getName(), mapParameters(method), methodHint));
180191
}
181192

193+
/**
194+
* Register the need for reflection on the specified {@link Method},
195+
* using the specified {@link ExecutableMode}.
196+
* @param method the method that requires reflection
197+
* @param mode the requested mode
198+
* @return {@code this}, to facilitate method chaining
199+
*/
200+
public ReflectionHints registerMethod(Method method, ExecutableMode mode) {
201+
return registerMethod(method, methodHint -> methodHint.withMode(mode));
202+
}
203+
182204
/**
183205
* Register the need for reflection on the specified {@link Method},
184206
* enabling {@link ExecutableMode#INVOKE}.
185207
* @param method the method that requires reflection
186208
* @return {@code this}, to facilitate method chaining
187209
*/
188210
public ReflectionHints registerMethod(Method method) {
189-
return registerMethod(method, methodHint -> methodHint.withMode(ExecutableMode.INVOKE));
211+
return registerMethod(method, ExecutableMode.INVOKE);
190212
}
191213

192214
private List<TypeReference> mapParameters(Executable executable) {

spring-core/src/test/java/org/springframework/aot/hint/ReflectionHintsTests.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,16 @@ void registerConstructor() {
176176
});
177177
}
178178

179+
@Test
180+
void registerConstructorWithMode() {
181+
this.reflectionHints.registerConstructor(
182+
TestType.class.getDeclaredConstructors()[0], ExecutableMode.INTROSPECT);
183+
assertTestTypeConstructorHint(constructorHint -> {
184+
assertThat(constructorHint.getParameterTypes()).isEmpty();
185+
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
186+
});
187+
}
188+
179189
@Test
180190
void registerConstructorWithEmptyCustomizerAppliesConsistentDefault() {
181191
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0],
@@ -219,6 +229,18 @@ void registerMethod() {
219229
});
220230
}
221231

232+
@Test
233+
void registerMethodWithMode() {
234+
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
235+
assertThat(method).isNotNull();
236+
this.reflectionHints.registerMethod(method, ExecutableMode.INTROSPECT);
237+
assertTestTypeMethodHints(methodHint -> {
238+
assertThat(methodHint.getName()).isEqualTo("setName");
239+
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
240+
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
241+
});
242+
}
243+
222244
@Test
223245
void registerMethodWithEmptyCustomizerAppliesConsistentDefault() {
224246
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);

spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/MessageMappingReflectiveProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ protected void registerTypeHints(ReflectionHints hints, Class<?> type) {
6464
}
6565

6666
protected void registerMethodHints(ReflectionHints hints, Method method) {
67-
hints.registerMethod(method, hint -> hint.withMode(ExecutableMode.INVOKE));
67+
hints.registerMethod(method, ExecutableMode.INVOKE);
6868
registerParameterHints(hints, method);
6969
registerReturnValueHints(hints, method);
7070
}
7171

7272
protected void registerParameterHints(ReflectionHints hints, Method method) {
73-
hints.registerMethod(method, hint -> hint.withMode(ExecutableMode.INVOKE));
73+
hints.registerMethod(method, ExecutableMode.INVOKE);
7474
for (Parameter parameter : method.getParameters()) {
7575
MethodParameter methodParameter = MethodParameter.forParameter(parameter);
7676
if (Message.class.isAssignableFrom(methodParameter.getParameterType())) {

spring-web/src/main/java/org/springframework/web/bind/annotation/RequestMappingReflectiveProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ protected void registerTypeHints(ReflectionHints hints, Class<?> type) {
6363
}
6464

6565
protected void registerMethodHints(ReflectionHints hints, Method method) {
66-
hints.registerMethod(method, hint -> hint.withMode(ExecutableMode.INVOKE));
66+
hints.registerMethod(method, ExecutableMode.INVOKE);
6767
registerParameterHints(hints, method);
6868
registerReturnValueHints(hints, method);
6969
}
7070

7171
protected void registerParameterHints(ReflectionHints hints, Method method) {
72-
hints.registerMethod(method, hint -> hint.withMode(ExecutableMode.INVOKE));
72+
hints.registerMethod(method, ExecutableMode.INVOKE);
7373
for (Parameter parameter : method.getParameters()) {
7474
MethodParameter methodParameter = MethodParameter.forParameter(parameter);
7575
if (methodParameter.hasParameterAnnotation(RequestBody.class) ||

0 commit comments

Comments
 (0)