Update AOT support after RuntimeHints changes

This commit adapts AOT support in various modules after the RuntimeHints
and related deprecation changes.

`MemberCategory.INTROSPECT_*` hints are now removed and
`MemberCategory.*_FIELDS` are  replaced with
`MemberCategory.INVOKE*_FIELDS` when invocation is needed.

Usage of `RuntimeHintsAgent` are also deprecated.

Closes gh-33847
This commit is contained in:
Brian Clozel
2024-11-29 14:44:05 +01:00
parent 0759129c14
commit ba312f6c7c
31 changed files with 81 additions and 111 deletions

View File

@@ -1065,7 +1065,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
}
else {
codeWarnings.detectDeprecation(method);
hints.reflection().registerMethod(method, ExecutableMode.INTROSPECT);
hints.reflection().registerType(method.getDeclaringClass());
CodeBlock arguments = new AutowiredArgumentsCodeGenerator(this.target,
method).generateCode(method.getParameterTypes());
CodeBlock injectionCode = CodeBlock.of("args -> $L.$L($L)",

View File

@@ -252,10 +252,10 @@ class BeanDefinitionPropertiesCodeGenerator {
// ReflectionUtils#findField searches recursively in the type hierarchy
Class<?> searchType = beanDefinition.getTargetType();
while (searchType != null && searchType != writeMethod.getDeclaringClass()) {
this.hints.reflection().registerType(searchType, MemberCategory.DECLARED_FIELDS);
this.hints.reflection().registerType(searchType, MemberCategory.INVOKE_DECLARED_FIELDS);
searchType = searchType.getSuperclass();
}
this.hints.reflection().registerType(writeMethod.getDeclaringClass(), MemberCategory.DECLARED_FIELDS);
this.hints.reflection().registerType(writeMethod.getDeclaringClass(), MemberCategory.INVOKE_DECLARED_FIELDS);
}
private void addQualifiers(CodeBlock.Builder code, RootBeanDefinition beanDefinition) {

View File

@@ -26,9 +26,9 @@ import org.springframework.aot.generate.GeneratedMethods;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.MethodReference;
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.ReflectionHints;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.TypeHint;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.javapoet.ClassName;
@@ -100,8 +100,8 @@ class BeanRegistrationsAotContribution
registrations.forEach(registration -> {
ReflectionHints hints = runtimeHints.reflection();
Class<?> beanClass = registration.registeredBean.getBeanClass();
hints.registerType(beanClass, MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS);
hints.registerForInterfaces(beanClass, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
hints.registerType(beanClass);
hints.registerForInterfaces(beanClass, TypeHint.Builder::withMembers);
});
}

View File

@@ -172,8 +172,7 @@ public class InstanceSupplierCodeGenerator {
}
private CodeBlock generateCodeForAccessibleConstructor(String beanName, Constructor<?> constructor) {
this.generationContext.getRuntimeHints().reflection().registerConstructor(
constructor, ExecutableMode.INTROSPECT);
this.generationContext.getRuntimeHints().reflection().registerType(constructor.getDeclaringClass());
if (constructor.getParameterCount() == 0) {
if (!this.allowDirectSupplierShortcut) {
@@ -265,7 +264,7 @@ public class InstanceSupplierCodeGenerator {
private CodeBlock generateCodeForAccessibleFactoryMethod(String beanName,
Method factoryMethod, Class<?> targetClass, @Nullable String factoryBeanName) {
this.generationContext.getRuntimeHints().reflection().registerMethod(factoryMethod, ExecutableMode.INTROSPECT);
this.generationContext.getRuntimeHints().reflection().registerType(factoryMethod.getDeclaringClass());
if (factoryBeanName == null && factoryMethod.getParameterCount() == 0) {
Class<?> suppliedType = ClassUtils.resolvePrimitiveIfNecessary(factoryMethod.getReturnType());

View File

@@ -574,7 +574,7 @@ class BeanDefinitionPropertiesCodeGeneratorTests {
private void assertHasDeclaredFieldsHint(Class<?> beanType) {
assertThat(RuntimeHintsPredicates.reflection()
.onType(beanType).withMemberCategory(MemberCategory.DECLARED_FIELDS))
.onType(beanType).withMemberCategory(MemberCategory.INVOKE_DECLARED_FIELDS))
.accepts(this.generationContext.getRuntimeHints());
}

View File

@@ -31,7 +31,6 @@ import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.MethodReference;
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
import org.springframework.aot.generate.ValueCodeGenerationException;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.Registration;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
@@ -149,14 +148,11 @@ class BeanRegistrationsAotContributionTests {
registeredBean, null, List.of());
BeanRegistrationsAotContribution contribution = createContribution(registeredBean, generator);
contribution.applyTo(this.generationContext, this.beanFactoryInitializationCode);
assertThat(reflection().onType(Employee.class)
.withMemberCategories(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS))
assertThat(reflection().onType(Employee.class))
.accepts(this.generationContext.getRuntimeHints());
assertThat(reflection().onType(ITestBean.class)
.withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS))
assertThat(reflection().onType(ITestBean.class))
.accepts(this.generationContext.getRuntimeHints());
assertThat(reflection().onType(AgeHolder.class)
.withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS))
assertThat(reflection().onType(AgeHolder.class))
.accepts(this.generationContext.getRuntimeHints());
}

View File

@@ -100,8 +100,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile())
.contains("InstanceSupplier.using(TestBean::new)");
});
assertThat(getReflectionHints().getTypeHint(TestBean.class))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(TestBean.class)).isNotNull();
}
@Test
@@ -112,8 +111,7 @@ class InstanceSupplierCodeGeneratorTests {
InjectionComponent bean = getBean(beanDefinition, instanceSupplier);
assertThat(bean).isInstanceOf(InjectionComponent.class).extracting("bean").isEqualTo("injected");
});
assertThat(getReflectionHints().getTypeHint(InjectionComponent.class))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(InjectionComponent.class)).isNotNull();
}
@Test
@@ -126,8 +124,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile()).contains(
"getBeanFactory().getBean(InnerComponentConfiguration.class).new NoDependencyComponent()");
});
assertThat(getReflectionHints().getTypeHint(NoDependencyComponent.class))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(NoDependencyComponent.class)).isNotNull();
}
@Test
@@ -141,8 +138,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile()).contains(
"getBeanFactory().getBean(InnerComponentConfiguration.class).new EnvironmentAwareComponent(");
});
assertThat(getReflectionHints().getTypeHint(EnvironmentAwareComponent.class))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(EnvironmentAwareComponent.class)).isNotNull();
}
@Test
@@ -184,8 +180,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(bean).extracting("number").isNull(); // No property actually set
assertThat(compiled.getSourceFile()).contains("NumberHolderFactoryBean::new");
});
assertThat(getReflectionHints().getTypeHint(NumberHolderFactoryBean.class))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(NumberHolderFactoryBean.class)).isNotNull();
}
@Test
@@ -215,8 +210,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile()).contains(
"getBeanFactory().getBean(\"config\", SimpleConfiguration.class).stringBean()");
});
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class)).isNotNull();
}
@Test
@@ -232,8 +226,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile()).contains(
"getBeanFactory().getBean(\"config\", DefaultSimpleBeanContract.class).simpleBean()");
});
assertThat(getReflectionHints().getTypeHint(SimpleBeanContract.class))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(SimpleBeanContract.class)).isNotNull();
}
@Test
@@ -268,8 +261,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(compiled.getSourceFile())
.contains("(registeredBean) -> SimpleConfiguration.integerBean()");
});
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class)).isNotNull();
}
@Test
@@ -287,8 +279,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(bean).isEqualTo("42test");
assertThat(compiled.getSourceFile()).contains("SampleFactory.create(");
});
assertThat(getReflectionHints().getTypeHint(SampleFactory.class))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(SampleFactory.class)).isNotNull();
}
@Test
@@ -305,8 +296,7 @@ class InstanceSupplierCodeGeneratorTests {
assertThat(bean).isEqualTo(42);
assertThat(compiled.getSourceFile()).doesNotContain(") throws Exception {");
});
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT));
assertThat(getReflectionHints().getTypeHint(SimpleConfiguration.class)).isNotNull();
}

View File

@@ -56,8 +56,7 @@ class InstanceSupplierCodeGeneratorKotlinTests {
Assertions.assertThat(bean).isInstanceOf(KotlinTestBean::class.java)
Assertions.assertThat(compiled.sourceFile).contains("InstanceSupplier.using(KotlinTestBean::new)")
}
Assertions.assertThat(getReflectionHints().getTypeHint(KotlinTestBean::class.java))
.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT))
Assertions.assertThat(getReflectionHints().getTypeHint(KotlinTestBean::class.java)).isNotNull
}
@Test
@@ -90,8 +89,7 @@ class InstanceSupplierCodeGeneratorKotlinTests {
"getBeanFactory().getBean(\"config\", KotlinConfiguration.class).stringBean()"
)
}
Assertions.assertThat<TypeHint?>(getReflectionHints().getTypeHint(KotlinConfiguration::class.java))
.satisfies(hasMethodWithMode(ExecutableMode.INTROSPECT))
Assertions.assertThat<TypeHint?>(getReflectionHints().getTypeHint(KotlinConfiguration::class.java)).isNotNull
}
@Test