Harmonize hint registration
Previously, a shortcut method for the default ExecutableMode was provided, but we found out that the shortcut makes it harder to determine the intent. This commit harmonizes hints registration for types, methods, and fields. An ExecutableMode is now mandatory to register a method or constructor. Previous methods that infer a mode or provided a customizer of the builder are deprecated. Closes gh-29135
This commit is contained in:
parent
c8f7a76659
commit
58a2b79699
|
|
@ -1007,7 +1007,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
|
||||||
AccessVisibility visibility = AccessVisibility.forMember(method);
|
AccessVisibility visibility = AccessVisibility.forMember(method);
|
||||||
if (visibility == AccessVisibility.PRIVATE
|
if (visibility == AccessVisibility.PRIVATE
|
||||||
|| visibility == AccessVisibility.PROTECTED) {
|
|| visibility == AccessVisibility.PROTECTED) {
|
||||||
hints.reflection().registerMethod(method);
|
hints.reflection().registerMethod(method, ExecutableMode.INVOKE);
|
||||||
code.add(".resolveAndInvoke($L, $L)", REGISTERED_BEAN_PARAMETER,
|
code.add(".resolveAndInvoke($L, $L)", REGISTERED_BEAN_PARAMETER,
|
||||||
INSTANCE_PARAMETER);
|
INSTANCE_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ class BeanDefinitionPropertiesCodeGenerator {
|
||||||
private void addInitDestroyHint(Class<?> beanUserClass, String methodName) {
|
private void addInitDestroyHint(Class<?> beanUserClass, String methodName) {
|
||||||
Method method = ReflectionUtils.findMethod(beanUserClass, methodName);
|
Method method = ReflectionUtils.findMethod(beanUserClass, methodName);
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
this.hints.reflection().registerMethod(method);
|
this.hints.reflection().registerMethod(method, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ class InstanceSupplierCodeGenerator {
|
||||||
Class<?> beanClass, Constructor<?> constructor, boolean dependsOnBean) {
|
Class<?> beanClass, Constructor<?> constructor, boolean dependsOnBean) {
|
||||||
|
|
||||||
this.generationContext.getRuntimeHints().reflection()
|
this.generationContext.getRuntimeHints().reflection()
|
||||||
.registerConstructor(constructor);
|
.registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||||
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method -> {
|
GeneratedMethod generatedMethod = generateGetInstanceSupplierMethod(method -> {
|
||||||
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
||||||
method.addModifiers(PRIVATE_STATIC);
|
method.addModifiers(PRIVATE_STATIC);
|
||||||
|
|
@ -240,7 +240,7 @@ class InstanceSupplierCodeGenerator {
|
||||||
Method factoryMethod, Class<?> declaringClass) {
|
Method factoryMethod, Class<?> declaringClass) {
|
||||||
|
|
||||||
this.generationContext.getRuntimeHints().reflection()
|
this.generationContext.getRuntimeHints().reflection()
|
||||||
.registerMethod(factoryMethod);
|
.registerMethod(factoryMethod, ExecutableMode.INVOKE);
|
||||||
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod(method -> {
|
GeneratedMethod getInstanceMethod = generateGetInstanceSupplierMethod(method -> {
|
||||||
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
method.addJavadoc("Get the bean instance supplier for '$L'.", beanName);
|
||||||
method.addModifiers(PRIVATE_STATIC);
|
method.addModifiers(PRIVATE_STATIC);
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ class InstrumentedMethodTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void classGetConstructorsShouldMatchConstructorReflectionHint() throws Exception {
|
void classGetConstructorsShouldMatchConstructorReflectionHint() throws Exception {
|
||||||
hints.reflection().registerConstructor(String.class.getConstructor());
|
hints.reflection().registerConstructor(String.class.getConstructor(), ExecutableMode.INVOKE);
|
||||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors);
|
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +250,7 @@ class InstrumentedMethodTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void classGetDeclaredConstructorsShouldMatchConstructorReflectionHint() throws Exception {
|
void classGetDeclaredConstructorsShouldMatchConstructorReflectionHint() throws Exception {
|
||||||
hints.reflection().registerConstructor(String.class.getConstructor());
|
hints.reflection().registerConstructor(String.class.getConstructor(), ExecutableMode.INVOKE);
|
||||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors);
|
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,7 +350,7 @@ class InstrumentedMethodTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void classGetDeclaredMethodsShouldMatchMethodReflectionHint() throws Exception {
|
void classGetDeclaredMethodsShouldMatchMethodReflectionHint() throws Exception {
|
||||||
hints.reflection().registerMethod(String.class.getMethod("toString"));
|
hints.reflection().registerMethod(String.class.getMethod("toString"), ExecutableMode.INVOKE);
|
||||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod);
|
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -392,7 +392,7 @@ class InstrumentedMethodTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void classGetMethodsShouldMatchMethodReflectionHint() throws Exception {
|
void classGetMethodsShouldMatchMethodReflectionHint() throws Exception {
|
||||||
hints.reflection().registerMethod(String.class.getMethod("toString"));
|
hints.reflection().registerMethod(String.class.getMethod("toString"), ExecutableMode.INVOKE);
|
||||||
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods);
|
assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ public class BindingReflectionHintsRegistrar {
|
||||||
Class<?> companionClass = ClassUtils.resolveClassName(companionClassName, null);
|
Class<?> companionClass = ClassUtils.resolveClassName(companionClassName, null);
|
||||||
Method serializerMethod = ClassUtils.getMethodIfAvailable(companionClass, "serializer");
|
Method serializerMethod = ClassUtils.getMethodIfAvailable(companionClass, "serializer");
|
||||||
if (serializerMethod != null) {
|
if (serializerMethod != null) {
|
||||||
hints.registerMethod(serializerMethod);
|
hints.registerMethod(serializerMethod, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ import org.springframework.util.ClassUtils;
|
||||||
* Gather the need for reflection at runtime.
|
* Gather the need for reflection at runtime.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public class ReflectionHints {
|
public class ReflectionHints {
|
||||||
|
|
@ -79,6 +81,7 @@ public class ReflectionHints {
|
||||||
* @param type the type to customize
|
* @param type the type to customize
|
||||||
* @param typeHint a builder to further customize hints for that type
|
* @param typeHint a builder to further customize hints for that type
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @see #registerType(TypeReference, MemberCategory...)
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerType(TypeReference type, Consumer<TypeHint.Builder> typeHint) {
|
public ReflectionHints registerType(TypeReference type, Consumer<TypeHint.Builder> typeHint) {
|
||||||
Builder builder = this.types.computeIfAbsent(type, TypeHint.Builder::new);
|
Builder builder = this.types.computeIfAbsent(type, TypeHint.Builder::new);
|
||||||
|
|
@ -93,8 +96,19 @@ public class ReflectionHints {
|
||||||
* @param memberCategories the member categories to apply
|
* @param memberCategories the member categories to apply
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerType(Class<?> type, MemberCategory... memberCategories) {
|
public ReflectionHints registerType(TypeReference type, MemberCategory... memberCategories) {
|
||||||
return registerType(TypeReference.of(type), memberCategories);
|
return registerType(type, TypeHint.builtWith(memberCategories));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register or customize reflection hints for the specified type.
|
||||||
|
* @param type the type to customize
|
||||||
|
* @param typeHint a builder to further customize hints for that type
|
||||||
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @see #registerType(Class, MemberCategory...)
|
||||||
|
*/
|
||||||
|
public ReflectionHints registerType(Class<?> type, Consumer<TypeHint.Builder> typeHint) {
|
||||||
|
return registerType(TypeReference.of(type), typeHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -104,18 +118,8 @@ public class ReflectionHints {
|
||||||
* @param memberCategories the member categories to apply
|
* @param memberCategories the member categories to apply
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerType(TypeReference type , MemberCategory... memberCategories) {
|
public ReflectionHints registerType(Class<?> type, MemberCategory... memberCategories) {
|
||||||
return registerType(type, TypeHint.builtWith(memberCategories));
|
return registerType(TypeReference.of(type), memberCategories);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register or customize reflection hints for the specified type.
|
|
||||||
* @param type the type to customize
|
|
||||||
* @param typeHint a builder to further customize hints for that type
|
|
||||||
* @return {@code this}, to facilitate method chaining
|
|
||||||
*/
|
|
||||||
public ReflectionHints registerType(Class<?> type, Consumer<TypeHint.Builder> typeHint) {
|
|
||||||
return registerType(TypeReference.of(type), typeHint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -125,6 +129,7 @@ public class ReflectionHints {
|
||||||
* @param typeName the type to customize
|
* @param typeName the type to customize
|
||||||
* @param typeHint a builder to further customize hints for that type
|
* @param typeHint a builder to further customize hints for that type
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @see #registerTypeIfPresent(ClassLoader, String, MemberCategory...)
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
|
public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
|
||||||
String typeName, Consumer<TypeHint.Builder> typeHint) {
|
String typeName, Consumer<TypeHint.Builder> typeHint) {
|
||||||
|
|
@ -134,6 +139,19 @@ public class ReflectionHints {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register or customize reflection hints for the specified type if it
|
||||||
|
* is available using the specified {@link ClassLoader}.
|
||||||
|
* @param classLoader the classloader to use to check if the type is present
|
||||||
|
* @param typeName the type to customize
|
||||||
|
* @param memberCategories the member categories to apply
|
||||||
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
*/
|
||||||
|
public ReflectionHints registerTypeIfPresent(@Nullable ClassLoader classLoader,
|
||||||
|
String typeName, MemberCategory... memberCategories) {
|
||||||
|
return registerTypeIfPresent(classLoader, typeName, TypeHint.builtWith(memberCategories));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register or customize reflection hints for the types defined by the
|
* Register or customize reflection hints for the types defined by the
|
||||||
* specified list of {@link TypeReference type references}. The specified
|
* specified list of {@link TypeReference type references}. The specified
|
||||||
|
|
@ -162,7 +180,9 @@ public class ReflectionHints {
|
||||||
* enabling {@link ExecutableMode#INVOKE}.
|
* enabling {@link ExecutableMode#INVOKE}.
|
||||||
* @param constructor the constructor that requires reflection
|
* @param constructor the constructor that requires reflection
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #registerConstructor(Constructor, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public ReflectionHints registerConstructor(Constructor<?> constructor) {
|
public ReflectionHints registerConstructor(Constructor<?> constructor) {
|
||||||
return registerConstructor(constructor, ExecutableMode.INVOKE);
|
return registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
@ -175,7 +195,8 @@ public class ReflectionHints {
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerConstructor(Constructor<?> constructor, ExecutableMode mode) {
|
public ReflectionHints registerConstructor(Constructor<?> constructor, ExecutableMode mode) {
|
||||||
return registerConstructor(constructor, ExecutableHint.builtWith(mode));
|
return registerType(TypeReference.of(constructor.getDeclaringClass()),
|
||||||
|
typeHint -> typeHint.withConstructor(mapParameters(constructor), mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -183,8 +204,10 @@ public class ReflectionHints {
|
||||||
* @param constructor the constructor that requires reflection
|
* @param constructor the constructor that requires reflection
|
||||||
* @param constructorHint a builder to further customize the hints of this
|
* @param constructorHint a builder to further customize the hints of this
|
||||||
* constructor
|
* constructor
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining`
|
||||||
|
* @deprecated in favor of {@link #registerConstructor(Constructor, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public ReflectionHints registerConstructor(Constructor<?> constructor, Consumer<ExecutableHint.Builder> constructorHint) {
|
public ReflectionHints registerConstructor(Constructor<?> constructor, Consumer<ExecutableHint.Builder> constructorHint) {
|
||||||
return registerType(TypeReference.of(constructor.getDeclaringClass()),
|
return registerType(TypeReference.of(constructor.getDeclaringClass()),
|
||||||
typeHint -> typeHint.withConstructor(mapParameters(constructor), constructorHint));
|
typeHint -> typeHint.withConstructor(mapParameters(constructor), constructorHint));
|
||||||
|
|
@ -195,7 +218,9 @@ public class ReflectionHints {
|
||||||
* enabling {@link ExecutableMode#INVOKE}.
|
* enabling {@link ExecutableMode#INVOKE}.
|
||||||
* @param method the method that requires reflection
|
* @param method the method that requires reflection
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #registerMethod(Method, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public ReflectionHints registerMethod(Method method) {
|
public ReflectionHints registerMethod(Method method) {
|
||||||
return registerMethod(method, ExecutableMode.INVOKE);
|
return registerMethod(method, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +233,8 @@ public class ReflectionHints {
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
*/
|
*/
|
||||||
public ReflectionHints registerMethod(Method method, ExecutableMode mode) {
|
public ReflectionHints registerMethod(Method method, ExecutableMode mode) {
|
||||||
return registerMethod(method, ExecutableHint.builtWith(mode));
|
return registerType(TypeReference.of(method.getDeclaringClass()),
|
||||||
|
typeHint -> typeHint.withMethod(method.getName(), mapParameters(method), mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -216,7 +242,9 @@ public class ReflectionHints {
|
||||||
* @param method the method that requires reflection
|
* @param method the method that requires reflection
|
||||||
* @param methodHint a builder to further customize the hints of this method
|
* @param methodHint a builder to further customize the hints of this method
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #registerMethod(Method, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public ReflectionHints registerMethod(Method method, Consumer<ExecutableHint.Builder> methodHint) {
|
public ReflectionHints registerMethod(Method method, Consumer<ExecutableHint.Builder> methodHint) {
|
||||||
return registerType(TypeReference.of(method.getDeclaringClass()),
|
return registerType(TypeReference.of(method.getDeclaringClass()),
|
||||||
typeHint -> typeHint.withMethod(method.getName(), mapParameters(method), methodHint));
|
typeHint -> typeHint.withMethod(method.getName(), mapParameters(method), methodHint));
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ import org.springframework.util.Assert;
|
||||||
* A hint that describes the need for reflection on a type.
|
* A hint that describes the need for reflection on a type.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @author Phillip Webb
|
||||||
|
* @author Andy Wilkinson
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
public final class TypeHint implements ConditionalHint {
|
public final class TypeHint implements ConditionalHint {
|
||||||
|
|
@ -199,7 +201,9 @@ public final class TypeHint implements ConditionalHint {
|
||||||
* parameter types, enabling {@link ExecutableMode#INVOKE}.
|
* parameter types, enabling {@link ExecutableMode#INVOKE}.
|
||||||
* @param parameterTypes the parameter types of the constructor
|
* @param parameterTypes the parameter types of the constructor
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #withConstructor(List, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder withConstructor(List<TypeReference> parameterTypes) {
|
public Builder withConstructor(List<TypeReference> parameterTypes) {
|
||||||
return withConstructor(parameterTypes, ExecutableMode.INVOKE);
|
return withConstructor(parameterTypes, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
@ -222,8 +226,11 @@ public final class TypeHint implements ConditionalHint {
|
||||||
* @param constructorHint a builder to further customize the hints of this
|
* @param constructorHint a builder to further customize the hints of this
|
||||||
* constructor
|
* constructor
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #withConstructor(List, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
public Builder withConstructor(List<TypeReference> parameterTypes, Consumer<ExecutableHint.Builder> constructorHint) {
|
@Deprecated
|
||||||
|
public Builder withConstructor(List<TypeReference> parameterTypes,
|
||||||
|
Consumer<ExecutableHint.Builder> constructorHint) {
|
||||||
ExecutableKey key = new ExecutableKey("<init>", parameterTypes);
|
ExecutableKey key = new ExecutableKey("<init>", parameterTypes);
|
||||||
ExecutableHint.Builder builder = this.constructors.computeIfAbsent(key,
|
ExecutableHint.Builder builder = this.constructors.computeIfAbsent(key,
|
||||||
k -> ExecutableHint.ofConstructor(parameterTypes));
|
k -> ExecutableHint.ofConstructor(parameterTypes));
|
||||||
|
|
@ -237,7 +244,9 @@ public final class TypeHint implements ConditionalHint {
|
||||||
* @param name the name of the method
|
* @param name the name of the method
|
||||||
* @param parameterTypes the parameter types of the constructor
|
* @param parameterTypes the parameter types of the constructor
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #withMethod(String, List, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder withMethod(String name, List<TypeReference> parameterTypes) {
|
public Builder withMethod(String name, List<TypeReference> parameterTypes) {
|
||||||
return withMethod(name, parameterTypes, ExecutableMode.INVOKE);
|
return withMethod(name, parameterTypes, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
@ -261,8 +270,11 @@ public final class TypeHint implements ConditionalHint {
|
||||||
* @param parameterTypes the parameter types of the constructor
|
* @param parameterTypes the parameter types of the constructor
|
||||||
* @param methodHint a builder to further customize the hints of this method
|
* @param methodHint a builder to further customize the hints of this method
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @deprecated in favor of {@link #withMethod(String, List, ExecutableMode)}
|
||||||
*/
|
*/
|
||||||
public Builder withMethod(String name, List<TypeReference> parameterTypes, Consumer<ExecutableHint.Builder> methodHint) {
|
@Deprecated
|
||||||
|
public Builder withMethod(String name, List<TypeReference> parameterTypes,
|
||||||
|
Consumer<ExecutableHint.Builder> methodHint) {
|
||||||
ExecutableKey key = new ExecutableKey(name, parameterTypes);
|
ExecutableKey key = new ExecutableKey(name, parameterTypes);
|
||||||
ExecutableHint.Builder builder = this.methods.computeIfAbsent(key,
|
ExecutableHint.Builder builder = this.methods.computeIfAbsent(key,
|
||||||
k -> ExecutableHint.ofMethod(name, parameterTypes));
|
k -> ExecutableHint.ofMethod(name, parameterTypes));
|
||||||
|
|
@ -274,6 +286,7 @@ public final class TypeHint implements ConditionalHint {
|
||||||
* Adds the specified {@linkplain MemberCategory member categories}.
|
* Adds the specified {@linkplain MemberCategory member categories}.
|
||||||
* @param memberCategories the categories to apply
|
* @param memberCategories the categories to apply
|
||||||
* @return {@code this}, to facilitate method chaining
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
* @see TypeHint#builtWith(MemberCategory...)
|
||||||
*/
|
*/
|
||||||
public Builder withMembers(MemberCategory... memberCategories) {
|
public Builder withMembers(MemberCategory... memberCategories) {
|
||||||
this.memberCategories.addAll(Arrays.asList(memberCategories));
|
this.memberCategories.addAll(Arrays.asList(memberCategories));
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.springframework.aot.hint.ExecutableMode;
|
||||||
import org.springframework.aot.hint.ReflectionHints;
|
import org.springframework.aot.hint.ReflectionHints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +65,7 @@ public class SimpleReflectiveProcessor implements ReflectiveProcessor {
|
||||||
* @param constructor the constructor to process
|
* @param constructor the constructor to process
|
||||||
*/
|
*/
|
||||||
protected void registerConstructorHint(ReflectionHints hints, Constructor<?> constructor) {
|
protected void registerConstructorHint(ReflectionHints hints, Constructor<?> constructor) {
|
||||||
hints.registerConstructor(constructor);
|
hints.registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -82,7 +83,7 @@ public class SimpleReflectiveProcessor implements ReflectiveProcessor {
|
||||||
* @param method the method to process
|
* @param method the method to process
|
||||||
*/
|
*/
|
||||||
protected void registerMethodHint(ReflectionHints hints, Method method) {
|
protected void registerMethodHint(ReflectionHints hints, Method method) {
|
||||||
hints.registerMethod(method);
|
hints.registerMethod(method, ExecutableMode.INVOKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.aot.hint;
|
package org.springframework.aot.hint;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
@ -48,8 +49,7 @@ class ReflectionHintsTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerTypeIfPresentRegistersExistingClass() {
|
void registerTypeIfPresentRegistersExistingClass() {
|
||||||
this.reflectionHints.registerTypeIfPresent(null, String.class.getName(),
|
this.reflectionHints.registerTypeIfPresent(null, String.class.getName(), MemberCategory.DECLARED_FIELDS);
|
||||||
hint -> hint.withMembers(MemberCategory.DECLARED_FIELDS));
|
|
||||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(
|
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(
|
||||||
typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS));
|
typeWithMemberCategories(String.class, MemberCategory.DECLARED_FIELDS));
|
||||||
}
|
}
|
||||||
|
|
@ -144,15 +144,6 @@ class ReflectionHintsTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerConstructor() {
|
void registerConstructor() {
|
||||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0]);
|
|
||||||
assertTestTypeConstructorHint(constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerConstructorWithMode() {
|
|
||||||
this.reflectionHints.registerConstructor(
|
this.reflectionHints.registerConstructor(
|
||||||
TestType.class.getDeclaredConstructors()[0], ExecutableMode.INTROSPECT);
|
TestType.class.getDeclaredConstructors()[0], ExecutableMode.INTROSPECT);
|
||||||
assertTestTypeConstructorHint(constructorHint -> {
|
assertTestTypeConstructorHint(constructorHint -> {
|
||||||
|
|
@ -162,25 +153,16 @@ class ReflectionHintsTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerConstructorWithEmptyCustomizerAppliesConsistentDefault() {
|
void registerConstructorTwiceUpdatesExistingEntry() {
|
||||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0],
|
Constructor<?> constructor = TestType.class.getDeclaredConstructors()[0];
|
||||||
constructorHint -> {});
|
this.reflectionHints.registerConstructor(constructor, ExecutableMode.INTROSPECT);
|
||||||
|
this.reflectionHints.registerConstructor(constructor, ExecutableMode.INVOKE);
|
||||||
assertTestTypeConstructorHint(constructorHint -> {
|
assertTestTypeConstructorHint(constructorHint -> {
|
||||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerConstructorWithCustomizerAppliesCustomization() {
|
|
||||||
this.reflectionHints.registerConstructor(TestType.class.getDeclaredConstructors()[0],
|
|
||||||
constructorHint -> constructorHint.withMode(ExecutableMode.INTROSPECT));
|
|
||||||
assertTestTypeConstructorHint(constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).isEmpty();
|
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTestTypeConstructorHint(Consumer<ExecutableHint> constructorHint) {
|
private void assertTestTypeConstructorHint(Consumer<ExecutableHint> constructorHint) {
|
||||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
||||||
assertThat(typeHint.getMemberCategories()).isEmpty();
|
assertThat(typeHint.getMemberCategories()).isEmpty();
|
||||||
|
|
@ -194,18 +176,6 @@ class ReflectionHintsTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerMethod() {
|
void registerMethod() {
|
||||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
|
||||||
assertThat(method).isNotNull();
|
|
||||||
this.reflectionHints.registerMethod(method);
|
|
||||||
assertTestTypeMethodHints(methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
|
||||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerMethodWithMode() {
|
|
||||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
this.reflectionHints.registerMethod(method, ExecutableMode.INTROSPECT);
|
this.reflectionHints.registerMethod(method, ExecutableMode.INTROSPECT);
|
||||||
|
|
@ -217,10 +187,11 @@ class ReflectionHintsTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void registerMethodWithEmptyCustomizerAppliesConsistentDefault() {
|
void registerMethodTwiceUpdatesExistingEntry() {
|
||||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
||||||
assertThat(method).isNotNull();
|
assertThat(method).isNotNull();
|
||||||
this.reflectionHints.registerMethod(method, methodHint -> {});
|
this.reflectionHints.registerMethod(method, ExecutableMode.INTROSPECT);
|
||||||
|
this.reflectionHints.registerMethod(method, ExecutableMode.INVOKE);
|
||||||
assertTestTypeMethodHints(methodHint -> {
|
assertTestTypeMethodHints(methodHint -> {
|
||||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
assertThat(methodHint.getName()).isEqualTo("setName");
|
||||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
||||||
|
|
@ -228,18 +199,6 @@ class ReflectionHintsTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void registerMethodWithCustomizerAppliesCustomization() {
|
|
||||||
Method method = ReflectionUtils.findMethod(TestType.class, "setName", String.class);
|
|
||||||
assertThat(method).isNotNull();
|
|
||||||
this.reflectionHints.registerMethod(method, methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT));
|
|
||||||
assertTestTypeMethodHints(methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("setName");
|
|
||||||
assertThat(methodHint.getParameterTypes()).containsOnly(TypeReference.of(String.class));
|
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assertTestTypeMethodHints(Consumer<ExecutableHint> methodHint) {
|
private void assertTestTypeMethodHints(Consumer<ExecutableHint> methodHint) {
|
||||||
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
assertThat(this.reflectionHints.typeHints()).singleElement().satisfies(typeHint -> {
|
||||||
assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName());
|
assertThat(typeHint.getType().getCanonicalName()).isEqualTo(TestType.class.getCanonicalName());
|
||||||
|
|
|
||||||
|
|
@ -70,16 +70,6 @@ class TypeHintTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createWithConstructor() {
|
void createWithConstructor() {
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
|
||||||
assertConstructorHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withConstructor(parameterTypes), constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).containsOnlyOnceElementsOf(parameterTypes);
|
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createWithConstructorAndMode() {
|
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
||||||
assertConstructorHint(TypeHint.of(TypeReference.of(String.class))
|
assertConstructorHint(TypeHint.of(TypeReference.of(String.class))
|
||||||
.withConstructor(parameterTypes, ExecutableMode.INTROSPECT), constructorHint -> {
|
.withConstructor(parameterTypes, ExecutableMode.INTROSPECT), constructorHint -> {
|
||||||
|
|
@ -89,45 +79,22 @@ class TypeHintTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createWithConstructorAndEmptyCustomizerAppliesConsistentDefault() {
|
void createWithConstructorWithSameConstructorUpdatesEntry() {
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
|
||||||
assertConstructorHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withConstructor(parameterTypes, constructorHint -> {}), constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).containsOnlyOnceElementsOf(parameterTypes);
|
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createWithConstructorAndCustomizerAppliesCustomization() {
|
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
|
||||||
assertConstructorHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withConstructor(parameterTypes, constructorHint ->
|
|
||||||
constructorHint.withMode(ExecutableMode.INTROSPECT)), constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).containsOnlyOnceElementsOf(parameterTypes);
|
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createConstructorReuseBuilder() {
|
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
||||||
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
||||||
.withConstructor(parameterTypes, ExecutableMode.INTROSPECT);
|
.withConstructor(parameterTypes, ExecutableMode.INTROSPECT);
|
||||||
assertConstructorHint(builder.withConstructor(parameterTypes, constructorHint ->
|
assertConstructorHint(builder.withConstructor(parameterTypes, ExecutableMode.INVOKE), constructorHint -> {
|
||||||
constructorHint.withMode(ExecutableMode.INVOKE)), constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createConstructorReuseBuilderAndApplyExecutableModePrecedence() {
|
void createWithConstructorAndSameConstructorAppliesExecutableModePrecedence() {
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
|
||||||
Builder builder = TypeHint.of(TypeReference.of(String.class)).withConstructor(parameterTypes,
|
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
||||||
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE));
|
.withConstructor(parameterTypes, ExecutableMode.INVOKE);
|
||||||
assertConstructorHint(builder.withConstructor(parameterTypes, constructorHint ->
|
assertConstructorHint(builder.withConstructor(parameterTypes, ExecutableMode.INTROSPECT), constructorHint -> {
|
||||||
constructorHint.withMode(ExecutableMode.INTROSPECT)), constructorHint -> {
|
|
||||||
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
assertThat(constructorHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||||
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
assertThat(constructorHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||||
});
|
});
|
||||||
|
|
@ -143,17 +110,6 @@ class TypeHintTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createWithMethod() {
|
void createWithMethod() {
|
||||||
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
|
|
||||||
assertMethodHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withMethod("valueOf", parameterTypes), methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
|
||||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createWithMethodAndMode() {
|
|
||||||
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
|
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
|
||||||
assertMethodHint(TypeHint.of(TypeReference.of(String.class))
|
assertMethodHint(TypeHint.of(TypeReference.of(String.class))
|
||||||
.withMethod("valueOf", parameterTypes, ExecutableMode.INTROSPECT), methodHint -> {
|
.withMethod("valueOf", parameterTypes, ExecutableMode.INTROSPECT), methodHint -> {
|
||||||
|
|
@ -164,36 +120,11 @@ class TypeHintTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createWithMethodAndEmptyCustomizerAppliesConsistentDefault() {
|
void createWithMethodWithSameMethodUpdatesEntry() {
|
||||||
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
|
|
||||||
assertMethodHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withMethod("valueOf", parameterTypes, methodHint -> {}), methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
|
||||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createWithMethodAndCustomizerAppliesCustomization() {
|
|
||||||
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
|
|
||||||
assertMethodHint(TypeHint.of(TypeReference.of(String.class))
|
|
||||||
.withMethod("valueOf", parameterTypes, methodHint ->
|
|
||||||
methodHint.withMode(ExecutableMode.INTROSPECT)), methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
|
||||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INTROSPECT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void createWithMethodReuseBuilder() {
|
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
||||||
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
||||||
.withMethod("valueOf", parameterTypes, ExecutableMode.INTROSPECT);
|
.withMethod("valueOf", parameterTypes, ExecutableMode.INTROSPECT);
|
||||||
assertMethodHint(builder.withMethod("valueOf", parameterTypes,
|
assertMethodHint(builder.withMethod("valueOf", parameterTypes, ExecutableMode.INVOKE), methodHint -> {
|
||||||
methodHint -> methodHint.withMode(ExecutableMode.INVOKE)), methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
||||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||||
|
|
@ -201,12 +132,11 @@ class TypeHintTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void createWithMethodReuseBuilderAndApplyExecutableModePrecedence() {
|
void createWithMethodAndSameMethodAppliesExecutableModePrecedence() {
|
||||||
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
|
||||||
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
Builder builder = TypeHint.of(TypeReference.of(String.class))
|
||||||
.withMethod("valueOf", parameterTypes, ExecutableMode.INVOKE);
|
.withMethod("valueOf", parameterTypes, ExecutableMode.INVOKE);
|
||||||
assertMethodHint(builder.withMethod("valueOf", parameterTypes,
|
assertMethodHint(builder.withMethod("valueOf", parameterTypes, ExecutableMode.INTROSPECT), methodHint -> {
|
||||||
methodHint -> methodHint.withMode(ExecutableMode.INTROSPECT)), methodHint -> {
|
|
||||||
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
assertThat(methodHint.getName()).isEqualTo("valueOf");
|
||||||
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
assertThat(methodHint.getParameterTypes()).containsExactlyElementsOf(parameterTypes);
|
||||||
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
assertThat(methodHint.getMode()).isEqualTo(ExecutableMode.INVOKE);
|
||||||
|
|
|
||||||
|
|
@ -303,7 +303,7 @@ class ReflectionHintsPredicatesTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void reflectionOnAnyConstructorMatchesConstructorReflection() {
|
void reflectionOnAnyConstructorMatchesConstructorReflection() {
|
||||||
runtimeHints.reflection().registerConstructor(publicConstructor);
|
runtimeHints.reflection().registerConstructor(publicConstructor, ExecutableMode.INVOKE);
|
||||||
assertPredicateMatches(reflection.onType(SampleClass.class).withAnyConstructor());
|
assertPredicateMatches(reflection.onType(SampleClass.class).withAnyConstructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -458,7 +458,7 @@ class ReflectionHintsPredicatesTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void reflectionOnAnyMethodMatchesMethodReflection() {
|
void reflectionOnAnyMethodMatchesMethodReflection() {
|
||||||
runtimeHints.reflection().registerMethod(publicMethod);
|
runtimeHints.reflection().registerMethod(publicMethod, ExecutableMode.INVOKE);
|
||||||
assertPredicateMatches(reflection.onType(SampleClass.class).withAnyMethod());
|
assertPredicateMatches(reflection.onType(SampleClass.class).withAnyMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ public class FileNativeConfigurationWriterTests {
|
||||||
.withField("DEFAULT_CHARSET")
|
.withField("DEFAULT_CHARSET")
|
||||||
.withField("defaultCharset")
|
.withField("defaultCharset")
|
||||||
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
|
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
|
||||||
.withMethod("setDefaultCharset", TypeReference.listOf(Charset.class))
|
.withMethod("setDefaultCharset", TypeReference.listOf(Charset.class), ExecutableMode.INVOKE)
|
||||||
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
||||||
generator.write(hints);
|
generator.write(hints);
|
||||||
assertEquals("""
|
assertEquals("""
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ public class ReflectionHintsWriterTests {
|
||||||
.withField("DEFAULT_CHARSET")
|
.withField("DEFAULT_CHARSET")
|
||||||
.withField("defaultCharset")
|
.withField("defaultCharset")
|
||||||
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
|
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), ExecutableMode.INTROSPECT)
|
||||||
.withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class)))
|
.withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class)), ExecutableMode.INVOKE)
|
||||||
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
.withMethod("getDefaultCharset", Collections.emptyList(), ExecutableMode.INTROSPECT));
|
||||||
assertEquals("""
|
assertEquals("""
|
||||||
[
|
[
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.springframework.aot.generate.AccessVisibility;
|
import org.springframework.aot.generate.AccessVisibility;
|
||||||
|
import org.springframework.aot.hint.ExecutableMode;
|
||||||
import org.springframework.aot.hint.RuntimeHints;
|
import org.springframework.aot.hint.RuntimeHints;
|
||||||
import org.springframework.javapoet.CodeBlock;
|
import org.springframework.javapoet.CodeBlock;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
@ -97,7 +98,7 @@ class InjectionCodeGenerator {
|
||||||
AccessVisibility visibility = AccessVisibility.forMember(method);
|
AccessVisibility visibility = AccessVisibility.forMember(method);
|
||||||
if (visibility == AccessVisibility.PRIVATE
|
if (visibility == AccessVisibility.PRIVATE
|
||||||
|| visibility == AccessVisibility.PROTECTED) {
|
|| visibility == AccessVisibility.PROTECTED) {
|
||||||
this.hints.reflection().registerMethod(method);
|
this.hints.reflection().registerMethod(method, ExecutableMode.INVOKE);
|
||||||
code.addStatement("$T method = $T.findMethod($T.class, $S, $T.class)",
|
code.addStatement("$T method = $T.findMethod($T.class, $S, $T.class)",
|
||||||
Method.class, ReflectionUtils.class, method.getDeclaringClass(),
|
Method.class, ReflectionUtils.class, method.getDeclaringClass(),
|
||||||
method.getName(), method.getParameterTypes()[0]);
|
method.getName(), method.getParameterTypes()[0]);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue