Fix reflection hint generation for properties nested in superclass

Fixes gh-36406
This commit is contained in:
Andy Wilkinson 2023-07-19 14:36:58 +01:00
parent 9d91dbc4e5
commit f145ca0c3c
2 changed files with 60 additions and 1 deletions

View File

@ -317,7 +317,8 @@ public class BindableRuntimeHintsRegistrar implements RuntimeHintsRegistrar {
* @return whether the specified {@code propertyType} is a nested type
*/
private boolean isNestedType(String propertyName, Class<?> propertyType) {
if (this.type.equals(propertyType.getDeclaringClass())) {
Class<?> declaringClass = propertyType.getDeclaringClass();
if (declaringClass != null && declaringClass.isAssignableFrom(this.type)) {
return true;
}
Field field = ReflectionUtils.findField(this.type, propertyName);

View File

@ -34,6 +34,7 @@ import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import org.springframework.boot.context.properties.BoundConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBean;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.boot.context.properties.bind.BindableRuntimeHintsRegistrarTests.BaseProperties.InheritedNested;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
@ -243,6 +244,21 @@ class BindableRuntimeHintsRegistrarTests {
"setBravo"));
}
@Test
void registerHintsWhenHasInheritedNestedProperties() {
RuntimeHints runtimeHints = registerHints(ExtendingProperties.class);
assertThat(runtimeHints.reflection().typeHints()).hasSize(3);
assertThat(runtimeHints.reflection().getTypeHint(BaseProperties.class)).satisfies((entry) -> {
assertThat(entry.getMemberCategories()).isEmpty();
assertThat(entry.methods()).extracting(ExecutableHint::getName)
.containsExactlyInAnyOrder("getInheritedNested", "setInheritedNested");
});
assertThat(runtimeHints.reflection().getTypeHint(ExtendingProperties.class))
.satisfies(javaBeanBinding(ExtendingProperties.class, "getBravo", "setBravo"));
assertThat(runtimeHints.reflection().getTypeHint(InheritedNested.class))
.satisfies(javaBeanBinding(InheritedNested.class, "getAlpha", "setAlpha"));
}
private Consumer<TypeHint> javaBeanBinding(Class<?> type, String... expectedMethods) {
return javaBeanBinding(type, type.getDeclaredConstructors()[0], expectedMethods);
}
@ -665,4 +681,46 @@ class BindableRuntimeHintsRegistrarTests {
}
public abstract static class BaseProperties {
private InheritedNested inheritedNested;
public InheritedNested getInheritedNested() {
return this.inheritedNested;
}
public void setInheritedNested(InheritedNested inheritedNested) {
this.inheritedNested = inheritedNested;
}
public static class InheritedNested {
private String alpha;
public String getAlpha() {
return this.alpha;
}
public void setAlpha(String alpha) {
this.alpha = alpha;
}
}
}
public static class ExtendingProperties extends BaseProperties {
private String bravo;
public String getBravo() {
return this.bravo;
}
public void setBravo(String bravo) {
this.bravo = bravo;
}
}
}