Add RuntimeHints predicates generator

The `RuntimeHints` API allows to describe hints for the reflection,
proxies and resources behavior at runtime. The need for a particular
behavior can be covered by several types of hints, at different levels.
This knowledge can be important in several cases:

* before contributing additional hints, infrastructure can check if an
  existing hint already covers the behavior
* this can be used in test suites and test infrastructure

This commit adds a new RuntimeHintsPredicates that generates `Predicate`
instances for testing `RuntimeHints` against a desired runtime behavior
for reflection, resources or proxies.

Closes gh-28555
This commit is contained in:
Brian Clozel
2022-06-10 17:04:54 +02:00
parent 100ce9642a
commit 9c9b2356ce
13 changed files with 1318 additions and 55 deletions

View File

@@ -29,6 +29,7 @@ import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.InMemoryGeneratedFiles;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsPredicates;
import org.springframework.aot.hint.TypeReference;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
@@ -96,8 +97,7 @@ class ReflectiveProcessorBeanRegistrationAotProcessorTests {
void shouldRegisterAnnotation() {
process(SampleMethodMetaAnnotatedBean.class);
RuntimeHints runtimeHints = this.generationContext.getRuntimeHints();
assertThat(runtimeHints.reflection().getTypeHint(SampleInvoker.class)).satisfies(typeHint ->
assertThat(typeHint.getMemberCategories()).containsOnly(MemberCategory.INVOKE_DECLARED_METHODS));
assertThat(RuntimeHintsPredicates.reflection().onType(SampleInvoker.class).withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(runtimeHints);
assertThat(runtimeHints.proxies().jdkProxies()).isEmpty();
}
@@ -105,11 +105,8 @@ class ReflectiveProcessorBeanRegistrationAotProcessorTests {
void shouldRegisterAnnotationAndProxyWithAliasFor() {
process(SampleMethodMetaAnnotatedBeanWithAlias.class);
RuntimeHints runtimeHints = this.generationContext.getRuntimeHints();
assertThat(runtimeHints.reflection().getTypeHint(RetryInvoker.class)).satisfies(typeHint ->
assertThat(typeHint.getMemberCategories()).containsOnly(MemberCategory.INVOKE_DECLARED_METHODS));
assertThat(runtimeHints.proxies().jdkProxies()).anySatisfy(jdkProxyHint ->
assertThat(jdkProxyHint.getProxiedInterfaces()).containsExactly(
TypeReference.of(RetryInvoker.class), TypeReference.of(SynthesizedAnnotation.class)));
assertThat(RuntimeHintsPredicates.reflection().onType(RetryInvoker.class).withMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(runtimeHints);
assertThat(RuntimeHintsPredicates.proxies().forInterfaces(RetryInvoker.class, SynthesizedAnnotation.class)).accepts(runtimeHints);
}
@Nullable
@@ -196,7 +193,7 @@ class ReflectiveProcessorBeanRegistrationAotProcessorTests {
}
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Reflective
@@ -206,7 +203,7 @@ class ReflectiveProcessorBeanRegistrationAotProcessorTests {
}
@Target({ ElementType.METHOD })
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SampleInvoker