From 1fd54912d2c6088adfca4d945326be5ed922b5d9 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Tue, 3 Oct 2023 11:24:47 +0200 Subject: [PATCH] Polish reflection hints on bean registration interfaces This commit ensures that we register reflection hints on interfaces in the entire type hierarchy. Closes gh-31350 --- .../aot/BeanRegistrationsAotContribution.java | 11 +++++++++-- .../BeanRegistrationsAotContributionTests.java | 16 ++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java index 58f66ddaaa..7b74a7b488 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContribution.java @@ -36,6 +36,7 @@ import org.springframework.core.ResolvableType; import org.springframework.javapoet.ClassName; import org.springframework.javapoet.CodeBlock; import org.springframework.javapoet.MethodSpec; +import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** @@ -118,8 +119,14 @@ class BeanRegistrationsAotContribution ReflectionHints hints = runtimeHints.reflection(); Class beanClass = beanRegistrationKey.beanClass(); hints.registerType(beanClass, MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS); - for (Class interfaceType : beanClass.getInterfaces()) { - hints.registerType(interfaceType, MemberCategory.INTROSPECT_PUBLIC_METHODS); + Class currentClass = beanClass; + while (currentClass != null && currentClass != Object.class) { + for (Class interfaceType : currentClass.getInterfaces()) { + if (!ClassUtils.isJavaLanguageInterface(interfaceType)) { + hints.registerType(interfaceType, MemberCategory.INTROSPECT_PUBLIC_METHODS); + } + } + currentClass = currentClass.getSuperclass(); } // Workaround for https://github.com/oracle/graal/issues/6510 if (beanClass.isRecord()) { diff --git a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java index eb58f97a8a..d9a0e337af 100644 --- a/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java @@ -36,7 +36,9 @@ import org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.Re import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.RegisteredBean; import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.testfixture.beans.Employee; import org.springframework.beans.testfixture.beans.GenericBeanWithBounds; +import org.springframework.beans.testfixture.beans.ITestBean; import org.springframework.beans.testfixture.beans.Person; import org.springframework.beans.testfixture.beans.RecordBean; import org.springframework.beans.testfixture.beans.TestBean; @@ -141,19 +143,17 @@ class BeanRegistrationsAotContributionTests { @Test void applyToRegisterReflectionHints() { - RegisteredBean registeredBean = registerBean(new RootBeanDefinition(TestBean.class)); + RegisteredBean registeredBean = registerBean(new RootBeanDefinition(Employee.class)); BeanDefinitionMethodGenerator generator = new BeanDefinitionMethodGenerator(this.methodGeneratorFactory, registeredBean, null, List.of()); - BeanRegistrationsAotContribution contribution = createContribution(TestBean.class, generator); + BeanRegistrationsAotContribution contribution = createContribution(Employee.class, generator); contribution.applyTo(this.generationContext, this.beanFactoryInitializationCode); - assertThat(reflection().onType(TestBean.class) + assertThat(reflection().onType(Employee.class) .withMemberCategories(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS)) .accepts(this.generationContext.getRuntimeHints()); - for (Class interfaceType : TestBean.class.getInterfaces()) { - assertThat(reflection().onType(interfaceType) - .withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS)) - .accepts(this.generationContext.getRuntimeHints()); - } + assertThat(reflection().onType(ITestBean.class) + .withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS)) + .accepts(this.generationContext.getRuntimeHints()); } @Test